@flywheel-io/vision 21.1.1 → 21.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { NgClass, CommonModule, NgStyle, NgTemplateOutlet, SlicePipe, Location } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, input, HostBinding, ChangeDetectionStrategy, Component, output, computed, NgModule, model, signal, effect, HostListener, ViewEncapsulation, EventEmitter, Output, ElementRef, ViewContainerRef, Directive, contentChildren, viewChild, ChangeDetectorRef, ContentChildren, Input, ViewChild, forwardRef, DestroyRef, Injectable, ContentChild, contentChild, NgZone, untracked, ViewChildren, viewChildren, linkedSignal, TemplateRef } from '@angular/core';
3
+ import { inject, input, HostBinding, ChangeDetectionStrategy, Component, output, computed, NgModule, model, signal, effect, HostListener, ViewEncapsulation, EventEmitter, Output, ElementRef, ViewContainerRef, Directive, contentChildren, viewChild, ChangeDetectorRef, ContentChildren, Input, ViewChild, forwardRef, DestroyRef, Injectable, ContentChild, contentChild, NgZone, untracked, DOCUMENT, ViewChildren, viewChildren, linkedSignal, TemplateRef } from '@angular/core';
4
4
  import { DomSanitizer } from '@angular/platform-browser';
5
5
  import { BehaviorSubject, debounce, timer, distinctUntilChanged, of, Subscription, min, combineLatest, tap, switchMap, map } from 'rxjs';
6
6
  import { CdkConnectedOverlay, OverlayModule, Overlay, CdkOverlayOrigin, OverlayContainer } from '@angular/cdk/overlay';
@@ -4884,7 +4884,7 @@ class FwTextInputComponent {
4884
4884
  useExisting: FwTextInputComponent,
4885
4885
  multi: true,
4886
4886
  },
4887
- ], queries: [{ propertyName: "contentChildInputElement", first: true, predicate: ["textInput"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"full-container\" [ngClass]=\"{ disabled: disabled() }\">\n <div class=\"input-container\" [class]=\"size()\">\n @if (!!leftIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onLeftIconClick()\" class=\"actionable\" [attr.aria-label]=\"leftIconLabel()\">\n <fw-icon>{{ leftIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ leftIcon() }}</fw-icon>\n }\n }\n @if (!!prefix()) {\n <p class=\"vision-p2 context\">{{ prefix() }}</p>\n }\n\n @if (!contentChildInputElement()) {\n <input\n #input\n [type]=\"type()\"\n (input)=\"changeHandler($event)\"\n (blur)=\"blurHandler()\"\n [attr.maxlength]=\"maxLength()\"\n [placeholder]=\"placeholder() || ''\"\n [readOnly]=\"readOnly()\"\n [disabled]=\"disabled()\"\n [autofocus]=\"autofocus()\"\n [autocomplete]=\"autocomplete()\"\n [required]=\"required()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error() ? true : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"computedDescribedBy()\"\n [attr.role]=\"role() || null\"\n [attr.aria-expanded]=\"ariaExpanded() === undefined ? null : ariaExpanded()\"\n [attr.aria-controls]=\"ariaControls() || null\"\n [attr.aria-autocomplete]=\"ariaAutocomplete() || null\"\n [attr.aria-activedescendant]=\"ariaActiveDescendant() || null\"\n />\n }\n <ng-content select=\"input\"></ng-content>\n @if (!!context()) {\n <p class=\"vision-p2 context\">{{ context() }}</p>\n }\n\n <fw-icon class=\"error-icon\" [fwTooltip]=\"errorInIconTooltip() ? errorText() || '' : ''\">warning-circle</fw-icon>\n @if (!!rightIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onRightIconClick()\" class=\"actionable\" [attr.aria-label]=\"rightIconLabel()\">\n <fw-icon>{{ rightIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ rightIcon() }}</fw-icon>\n }\n }\n <ng-content></ng-content>\n </div>\n @if (!!helperText()) {\n <p class=\"vision-p4 helper-text\" [id]=\"helperTextId\">{{ helperText() }}</p>\n }\n @if (!!errorText() && !errorInIconTooltip()) {\n <p class=\"vision-p4 error-text\" [id]=\"errorTextId\">{{ errorText() }}</p>\n }\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700\";.vision-h1{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:22px}.vision-h2{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:18px}.vision-h3{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:16px}.vision-h4{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:14px}.vision-h5{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:12px;line-height:130%}.vision-h6{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:10px;line-height:120%}.vision-p1{font-size:18px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p2{font-size:14px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p3{font-size:12px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p4{font-size:10px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p5{font-size:8px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-link{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link:hover{text-decoration:none}.vision-link:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link:visited{color:var(--secondary-base)}.vision-link-inherited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-inherited:hover{text-decoration:none}.vision-link-inherited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-inherited:visited{color:var(--secondary-base)}.vision-link-inherited,.vision-link-inherited:visited{color:inherit}.vision-link-no-visited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-no-visited:hover{text-decoration:none}.vision-link-no-visited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-no-visited:visited{color:var(--secondary-base)}.vision-link-no-visited:visited{color:var(--primary-base)}.full-container.disabled{cursor:not-allowed}.full-container.disabled fw-icon{cursor:not-allowed!important}.full-container{display:flex;flex-direction:column;line-height:21px}.full-container .input-container{box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;padding:8px;align-items:center;gap:5px;border-radius:6px;border:1px solid var(--separations-input);font-family:Inter,sans-serif}.full-container .input-container:focus-within{border:1px solid var(--primary-base)}.full-container .input-container input{min-width:0;font-size:14px;flex-grow:1;color:var(--typography-base);background:var(--page-light);border:none}.full-container .input-container input:focus{outline:none;border:none}.full-container .input-container input::placeholder{color:var(--typography-light)}.full-container .input-container .context{color:var(--typography-light)}.full-container .error-icon{display:none}.full-container .helper-text,.full-container .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0}.full-container .error-text{text-align:left;color:var(--red-base);display:none}.actionable{cursor:pointer}.actionable:hover{color:var(--primary-base);background-color:var(--primary-hover);border-radius:50%}.small{height:30px}.small fw-icon{font-size:18px;min-width:18px;width:18px}.medium{height:36px}.medium fw-icon{font-size:20px;min-width:20px;width:20px}.large{height:40px}.large fw-icon{font-size:24px;min-width:24px;width:24px}:host.errored .input-container,:host.ng-touched.ng-invalid .input-container{border:1px solid var(--red-base)}:host.errored .error-icon,:host.ng-touched.ng-invalid .error-icon{color:var(--red-base);display:inline!important}:host.errored .helper-text,:host.errored .full-container .error-text,:host.ng-touched.ng-invalid .helper-text,:host.ng-touched.ng-invalid .full-container .error-text{display:none}:host.errored .error-text,:host.ng-touched.ng-invalid .error-text{display:block!important}:disabled{opacity:.4;cursor:not-allowed}.disabled .actionable:hover{color:var(--typography-light);background-color:transparent}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FwIconComponent, selector: "fw-icon", inputs: ["ariaLabel", "size", "color"] }, { kind: "directive", type: FwTooltipDirective, selector: "[fwTooltip]", inputs: ["fwTooltip", "fwTooltipPosition", "fwTooltipMaxWidthPx", "fwTooltipClass", "fwTooltipDelay", "fwTooltipCaret", "fwTooltipEnabled"], outputs: ["fwTooltipChange", "fwTooltipPositionChange", "fwTooltipMaxWidthPxChange", "fwTooltipClassChange", "fwTooltipEnabledChange"] }, { kind: "directive", type: FwClickableDivDirective, selector: "[fwClickableDiv]", inputs: ["fwClickableDivDisabled", "fwClickableDivRole"] }] }); }
4887
+ ], queries: [{ propertyName: "contentChildInputElement", first: true, predicate: ["textInput"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"full-container\" [ngClass]=\"{ disabled: disabled() }\">\n <div class=\"input-container\" [class]=\"size()\">\n @if (!!leftIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onLeftIconClick()\" class=\"actionable\" [attr.aria-label]=\"leftIconLabel()\">\n <fw-icon>{{ leftIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ leftIcon() }}</fw-icon>\n }\n }\n @if (!!prefix()) {\n <p class=\"vision-p2 context\">{{ prefix() }}</p>\n }\n\n @if (!contentChildInputElement()) {\n <input\n #input\n [type]=\"type()\"\n (input)=\"changeHandler($event)\"\n (blur)=\"blurHandler()\"\n [attr.maxlength]=\"maxLength()\"\n [placeholder]=\"placeholder() || ''\"\n [readOnly]=\"readOnly()\"\n [disabled]=\"disabled()\"\n [autofocus]=\"autofocus()\"\n [autocomplete]=\"autocomplete()\"\n [required]=\"required()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error() ? true : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"computedDescribedBy()\"\n [attr.role]=\"role() || null\"\n [attr.aria-expanded]=\"ariaExpanded() === undefined ? null : ariaExpanded()\"\n [attr.aria-controls]=\"ariaControls() || null\"\n [attr.aria-autocomplete]=\"ariaAutocomplete() || null\"\n [attr.aria-activedescendant]=\"ariaActiveDescendant() || null\"\n />\n }\n <ng-content select=\"input\"></ng-content>\n @if (!!context()) {\n <p class=\"vision-p2 context\">{{ context() }}</p>\n }\n\n <fw-icon class=\"error-icon\" [fwTooltip]=\"errorInIconTooltip() ? errorText() || '' : ''\">warning-circle</fw-icon>\n @if (!!rightIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onRightIconClick()\" class=\"actionable\" [attr.aria-label]=\"rightIconLabel()\">\n <fw-icon>{{ rightIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ rightIcon() }}</fw-icon>\n }\n }\n <ng-content></ng-content>\n </div>\n @if (!!helperText()) {\n <p class=\"vision-p4 helper-text\" [id]=\"helperTextId\">{{ helperText() }}</p>\n }\n @if (!!errorText() && !errorInIconTooltip()) {\n <p class=\"vision-p4 error-text\" [id]=\"errorTextId\">{{ errorText() }}</p>\n }\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700\";.vision-h1{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:22px}.vision-h2{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:18px}.vision-h3{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:16px}.vision-h4{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:14px}.vision-h5{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:12px;line-height:130%}.vision-h6{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:10px;line-height:120%}.vision-p1{font-size:18px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p2{font-size:14px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p3{font-size:12px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p4{font-size:10px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p5{font-size:8px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-link{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link:hover{text-decoration:none}.vision-link:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link:visited{color:var(--secondary-base)}.vision-link-inherited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-inherited:hover{text-decoration:none}.vision-link-inherited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-inherited:visited{color:var(--secondary-base)}.vision-link-inherited,.vision-link-inherited:visited{color:inherit}.vision-link-no-visited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-no-visited:hover{text-decoration:none}.vision-link-no-visited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-no-visited:visited{color:var(--secondary-base)}.vision-link-no-visited:visited{color:var(--primary-base)}.full-container.disabled{cursor:not-allowed}.full-container.disabled fw-icon{cursor:not-allowed!important}.full-container{display:flex;flex-direction:column;line-height:21px}.full-container .input-container{box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;padding:8px;align-items:center;gap:5px;border-radius:6px;border:1px solid var(--separations-input);font-family:Inter,sans-serif}.full-container .input-container:focus-within{border:1px solid var(--primary-base)}.full-container .input-container input{min-width:0;font-size:14px;flex-grow:1;color:var(--typography-base);background:var(--page-light);border:none}.full-container .input-container input:focus{outline:none;border:none}.full-container .input-container input::placeholder{color:var(--typography-light)}.full-container .input-container .context{color:var(--typography-light)}.full-container .error-icon{display:none}.full-container .helper-text,.full-container .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0}.full-container .error-text{text-align:left;color:var(--red-base);display:none}.actionable{cursor:pointer}.actionable:hover{color:var(--primary-base);background-color:var(--primary-hover);border-radius:50%}.small{height:30px}.small fw-icon{font-size:18px;min-width:18px;width:18px}.medium{height:36px}.medium fw-icon{font-size:20px;min-width:20px;width:20px}.large{height:40px}.large fw-icon{font-size:24px;min-width:24px;width:24px}:host.errored .input-container,:host.ng-touched.ng-invalid .input-container{border:1px solid var(--red-base)}:host.errored .input-container:focus-within,:host.ng-touched.ng-invalid .input-container:focus-within{border:1px solid var(--red-base)}:host.errored .error-icon,:host.ng-touched.ng-invalid .error-icon{color:var(--red-base);display:inline!important}:host.errored .helper-text,:host.errored .full-container .error-text,:host.ng-touched.ng-invalid .helper-text,:host.ng-touched.ng-invalid .full-container .error-text{display:none}:host.errored .error-text,:host.ng-touched.ng-invalid .error-text{display:block!important}:disabled{opacity:.4;cursor:not-allowed}.disabled .actionable:hover{color:var(--typography-light);background-color:transparent}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FwIconComponent, selector: "fw-icon", inputs: ["ariaLabel", "size", "color"] }, { kind: "directive", type: FwTooltipDirective, selector: "[fwTooltip]", inputs: ["fwTooltip", "fwTooltipPosition", "fwTooltipMaxWidthPx", "fwTooltipClass", "fwTooltipDelay", "fwTooltipCaret", "fwTooltipEnabled"], outputs: ["fwTooltipChange", "fwTooltipPositionChange", "fwTooltipMaxWidthPxChange", "fwTooltipClassChange", "fwTooltipEnabledChange"] }, { kind: "directive", type: FwClickableDivDirective, selector: "[fwClickableDiv]", inputs: ["fwClickableDivDisabled", "fwClickableDivRole"] }] }); }
4888
4888
  }
4889
4889
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwTextInputComponent, decorators: [{
4890
4890
  type: Component,
@@ -4897,7 +4897,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
4897
4897
  ], host: {
4898
4898
  '[class.errored]': 'error()',
4899
4899
  '[style.width]': 'width()',
4900
- }, imports: [NgClass, FwIconComponent, FwTooltipDirective, FwClickableDivDirective], template: "<div class=\"full-container\" [ngClass]=\"{ disabled: disabled() }\">\n <div class=\"input-container\" [class]=\"size()\">\n @if (!!leftIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onLeftIconClick()\" class=\"actionable\" [attr.aria-label]=\"leftIconLabel()\">\n <fw-icon>{{ leftIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ leftIcon() }}</fw-icon>\n }\n }\n @if (!!prefix()) {\n <p class=\"vision-p2 context\">{{ prefix() }}</p>\n }\n\n @if (!contentChildInputElement()) {\n <input\n #input\n [type]=\"type()\"\n (input)=\"changeHandler($event)\"\n (blur)=\"blurHandler()\"\n [attr.maxlength]=\"maxLength()\"\n [placeholder]=\"placeholder() || ''\"\n [readOnly]=\"readOnly()\"\n [disabled]=\"disabled()\"\n [autofocus]=\"autofocus()\"\n [autocomplete]=\"autocomplete()\"\n [required]=\"required()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error() ? true : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"computedDescribedBy()\"\n [attr.role]=\"role() || null\"\n [attr.aria-expanded]=\"ariaExpanded() === undefined ? null : ariaExpanded()\"\n [attr.aria-controls]=\"ariaControls() || null\"\n [attr.aria-autocomplete]=\"ariaAutocomplete() || null\"\n [attr.aria-activedescendant]=\"ariaActiveDescendant() || null\"\n />\n }\n <ng-content select=\"input\"></ng-content>\n @if (!!context()) {\n <p class=\"vision-p2 context\">{{ context() }}</p>\n }\n\n <fw-icon class=\"error-icon\" [fwTooltip]=\"errorInIconTooltip() ? errorText() || '' : ''\">warning-circle</fw-icon>\n @if (!!rightIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onRightIconClick()\" class=\"actionable\" [attr.aria-label]=\"rightIconLabel()\">\n <fw-icon>{{ rightIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ rightIcon() }}</fw-icon>\n }\n }\n <ng-content></ng-content>\n </div>\n @if (!!helperText()) {\n <p class=\"vision-p4 helper-text\" [id]=\"helperTextId\">{{ helperText() }}</p>\n }\n @if (!!errorText() && !errorInIconTooltip()) {\n <p class=\"vision-p4 error-text\" [id]=\"errorTextId\">{{ errorText() }}</p>\n }\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700\";.vision-h1{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:22px}.vision-h2{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:18px}.vision-h3{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:16px}.vision-h4{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:14px}.vision-h5{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:12px;line-height:130%}.vision-h6{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:10px;line-height:120%}.vision-p1{font-size:18px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p2{font-size:14px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p3{font-size:12px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p4{font-size:10px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p5{font-size:8px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-link{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link:hover{text-decoration:none}.vision-link:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link:visited{color:var(--secondary-base)}.vision-link-inherited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-inherited:hover{text-decoration:none}.vision-link-inherited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-inherited:visited{color:var(--secondary-base)}.vision-link-inherited,.vision-link-inherited:visited{color:inherit}.vision-link-no-visited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-no-visited:hover{text-decoration:none}.vision-link-no-visited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-no-visited:visited{color:var(--secondary-base)}.vision-link-no-visited:visited{color:var(--primary-base)}.full-container.disabled{cursor:not-allowed}.full-container.disabled fw-icon{cursor:not-allowed!important}.full-container{display:flex;flex-direction:column;line-height:21px}.full-container .input-container{box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;padding:8px;align-items:center;gap:5px;border-radius:6px;border:1px solid var(--separations-input);font-family:Inter,sans-serif}.full-container .input-container:focus-within{border:1px solid var(--primary-base)}.full-container .input-container input{min-width:0;font-size:14px;flex-grow:1;color:var(--typography-base);background:var(--page-light);border:none}.full-container .input-container input:focus{outline:none;border:none}.full-container .input-container input::placeholder{color:var(--typography-light)}.full-container .input-container .context{color:var(--typography-light)}.full-container .error-icon{display:none}.full-container .helper-text,.full-container .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0}.full-container .error-text{text-align:left;color:var(--red-base);display:none}.actionable{cursor:pointer}.actionable:hover{color:var(--primary-base);background-color:var(--primary-hover);border-radius:50%}.small{height:30px}.small fw-icon{font-size:18px;min-width:18px;width:18px}.medium{height:36px}.medium fw-icon{font-size:20px;min-width:20px;width:20px}.large{height:40px}.large fw-icon{font-size:24px;min-width:24px;width:24px}:host.errored .input-container,:host.ng-touched.ng-invalid .input-container{border:1px solid var(--red-base)}:host.errored .error-icon,:host.ng-touched.ng-invalid .error-icon{color:var(--red-base);display:inline!important}:host.errored .helper-text,:host.errored .full-container .error-text,:host.ng-touched.ng-invalid .helper-text,:host.ng-touched.ng-invalid .full-container .error-text{display:none}:host.errored .error-text,:host.ng-touched.ng-invalid .error-text{display:block!important}:disabled{opacity:.4;cursor:not-allowed}.disabled .actionable:hover{color:var(--typography-light);background-color:transparent}\n"] }]
4900
+ }, imports: [NgClass, FwIconComponent, FwTooltipDirective, FwClickableDivDirective], template: "<div class=\"full-container\" [ngClass]=\"{ disabled: disabled() }\">\n <div class=\"input-container\" [class]=\"size()\">\n @if (!!leftIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onLeftIconClick()\" class=\"actionable\" [attr.aria-label]=\"leftIconLabel()\">\n <fw-icon>{{ leftIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ leftIcon() }}</fw-icon>\n }\n }\n @if (!!prefix()) {\n <p class=\"vision-p2 context\">{{ prefix() }}</p>\n }\n\n @if (!contentChildInputElement()) {\n <input\n #input\n [type]=\"type()\"\n (input)=\"changeHandler($event)\"\n (blur)=\"blurHandler()\"\n [attr.maxlength]=\"maxLength()\"\n [placeholder]=\"placeholder() || ''\"\n [readOnly]=\"readOnly()\"\n [disabled]=\"disabled()\"\n [autofocus]=\"autofocus()\"\n [autocomplete]=\"autocomplete()\"\n [required]=\"required()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-invalid]=\"error() ? true : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"computedDescribedBy()\"\n [attr.role]=\"role() || null\"\n [attr.aria-expanded]=\"ariaExpanded() === undefined ? null : ariaExpanded()\"\n [attr.aria-controls]=\"ariaControls() || null\"\n [attr.aria-autocomplete]=\"ariaAutocomplete() || null\"\n [attr.aria-activedescendant]=\"ariaActiveDescendant() || null\"\n />\n }\n <ng-content select=\"input\"></ng-content>\n @if (!!context()) {\n <p class=\"vision-p2 context\">{{ context() }}</p>\n }\n\n <fw-icon class=\"error-icon\" [fwTooltip]=\"errorInIconTooltip() ? errorText() || '' : ''\">warning-circle</fw-icon>\n @if (!!rightIcon()) {\n @if (useActionableIcons()) {\n <div fwClickableDiv (click)=\"onRightIconClick()\" class=\"actionable\" [attr.aria-label]=\"rightIconLabel()\">\n <fw-icon>{{ rightIcon() }}</fw-icon>\n </div>\n } @else {\n <fw-icon>{{ rightIcon() }}</fw-icon>\n }\n }\n <ng-content></ng-content>\n </div>\n @if (!!helperText()) {\n <p class=\"vision-p4 helper-text\" [id]=\"helperTextId\">{{ helperText() }}</p>\n }\n @if (!!errorText() && !errorInIconTooltip()) {\n <p class=\"vision-p4 error-text\" [id]=\"errorTextId\">{{ errorText() }}</p>\n }\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700\";.vision-h1{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:22px}.vision-h2{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:18px}.vision-h3{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:16px}.vision-h4{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:14px}.vision-h5{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:12px;line-height:130%}.vision-h6{font-family:Inter,sans-serif;color:var(--typography-base);font-weight:500;font-size:10px;line-height:120%}.vision-p1{font-size:18px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p2{font-size:14px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p3{font-size:12px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p4{font-size:10px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-p5{font-size:8px;font-family:Inter,sans-serif;color:var(--typography-base);font-weight:400}.vision-link{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link:hover{text-decoration:none}.vision-link:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link:visited{color:var(--secondary-base)}.vision-link-inherited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-inherited:hover{text-decoration:none}.vision-link-inherited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-inherited:visited{color:var(--secondary-base)}.vision-link-inherited,.vision-link-inherited:visited{color:inherit}.vision-link-no-visited{text-decoration:underline;color:var(--primary-base);cursor:pointer}.vision-link-no-visited:hover{text-decoration:none}.vision-link-no-visited:active{text-decoration:none;outline:2px solid var(--primary-dark);border-radius:4px}.vision-link-no-visited:visited{color:var(--secondary-base)}.vision-link-no-visited:visited{color:var(--primary-base)}.full-container.disabled{cursor:not-allowed}.full-container.disabled fw-icon{cursor:not-allowed!important}.full-container{display:flex;flex-direction:column;line-height:21px}.full-container .input-container{box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;padding:8px;align-items:center;gap:5px;border-radius:6px;border:1px solid var(--separations-input);font-family:Inter,sans-serif}.full-container .input-container:focus-within{border:1px solid var(--primary-base)}.full-container .input-container input{min-width:0;font-size:14px;flex-grow:1;color:var(--typography-base);background:var(--page-light);border:none}.full-container .input-container input:focus{outline:none;border:none}.full-container .input-container input::placeholder{color:var(--typography-light)}.full-container .input-container .context{color:var(--typography-light)}.full-container .error-icon{display:none}.full-container .helper-text,.full-container .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0}.full-container .error-text{text-align:left;color:var(--red-base);display:none}.actionable{cursor:pointer}.actionable:hover{color:var(--primary-base);background-color:var(--primary-hover);border-radius:50%}.small{height:30px}.small fw-icon{font-size:18px;min-width:18px;width:18px}.medium{height:36px}.medium fw-icon{font-size:20px;min-width:20px;width:20px}.large{height:40px}.large fw-icon{font-size:24px;min-width:24px;width:24px}:host.errored .input-container,:host.ng-touched.ng-invalid .input-container{border:1px solid var(--red-base)}:host.errored .input-container:focus-within,:host.ng-touched.ng-invalid .input-container:focus-within{border:1px solid var(--red-base)}:host.errored .error-icon,:host.ng-touched.ng-invalid .error-icon{color:var(--red-base);display:inline!important}:host.errored .helper-text,:host.errored .full-container .error-text,:host.ng-touched.ng-invalid .helper-text,:host.ng-touched.ng-invalid .full-container .error-text{display:none}:host.errored .error-text,:host.ng-touched.ng-invalid .error-text{display:block!important}:disabled{opacity:.4;cursor:not-allowed}.disabled .actionable:hover{color:var(--typography-light);background-color:transparent}\n"] }]
4901
4901
  }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], useActionableIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "useActionableIcons", required: false }] }], leftIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leftIcon", required: false }] }], rightIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "rightIcon", required: false }] }], leftIconLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "leftIconLabel", required: false }] }], rightIconLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rightIconLabel", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], ariaExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaExpanded", required: false }] }], ariaControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaControls", required: false }] }], ariaAutocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaAutocomplete", required: false }] }], ariaActiveDescendant: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaActiveDescendant", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], errorInIconTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorInIconTooltip", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], value: [{
4902
4902
  type: Input
4903
4903
  }], inputRef: [{
@@ -5059,6 +5059,11 @@ class FwMenuContainerComponent {
5059
5059
  constructor() {
5060
5060
  this.sanitizer = inject(DomSanitizer);
5061
5061
  this.ngZone = inject(NgZone);
5062
+ /**
5063
+ * The container's own element. Exposed because this component is usually rendered into a cdk
5064
+ * overlay, so a consumer holding the instance has no other way to reach the rendered panel.
5065
+ */
5066
+ this.hostElement = inject(ElementRef).nativeElement;
5062
5067
  this.menuWrapperRef = viewChild('menuWrapper', { ...(ngDevMode ? { debugName: "menuWrapperRef" } : /* istanbul ignore next */ {}), read: HTMLElement });
5063
5068
  this.canScrollUp = signal(false, ...(ngDevMode ? [{ debugName: "canScrollUp" }] : /* istanbul ignore next */ []));
5064
5069
  this.canScrollDown = signal(false, ...(ngDevMode ? [{ debugName: "canScrollDown" }] : /* istanbul ignore next */ []));
@@ -5831,6 +5836,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
5831
5836
  args: ['click']
5832
5837
  }] } });
5833
5838
 
5839
+ /**
5840
+ * Whether an event originated on, or inside, any of the given elements.
5841
+ *
5842
+ * Shared by `fw-select` and `fw-multi-select` so that both decide "inside vs outside" identically -
5843
+ * the trigger lives in the component's own view while the options panel is rendered into a cdk
5844
+ * overlay somewhere else in the document, so containment has to be checked against both.
5845
+ */
5846
+ function isEventInside(event, ...elements) {
5847
+ const candidates = elements.filter((element) => Boolean(element));
5848
+ if (candidates.length === 0) {
5849
+ return false;
5850
+ }
5851
+ // The path is resolved at dispatch time, so it still holds up for targets that a handler earlier
5852
+ // in the chain has already detached from the DOM
5853
+ const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
5854
+ if (path.length > 0) {
5855
+ return candidates.some((element) => path.includes(element));
5856
+ }
5857
+ const target = event.target;
5858
+ if (!(target instanceof Node)) {
5859
+ return false;
5860
+ }
5861
+ return candidates.some((element) => element.contains(target));
5862
+ }
5863
+
5834
5864
  /* eslint-disable @typescript-eslint/no-explicit-any */
5835
5865
  /**
5836
5866
  * Form control component for selecting multiple options from a dropdown, displaying selected values as chips
@@ -5839,7 +5869,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
5839
5869
  class FwMultiSelectMenuComponent {
5840
5870
  constructor() {
5841
5871
  this.elementRef = inject(ElementRef);
5872
+ this.document = inject(DOCUMENT);
5842
5873
  this.listboxId = inject(_IdGenerator).getId('fw-multi-select-listbox-');
5874
+ this.documentClickListener = (event) => this.outsideClick(event);
5843
5875
  // options
5844
5876
  this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
5845
5877
  this.valueProperty = input('value', ...(ngDevMode ? [{ debugName: "valueProperty" }] : /* istanbul ignore next */ []));
@@ -5864,6 +5896,12 @@ class FwMultiSelectMenuComponent {
5864
5896
  this.minOptionsHeight = input(...(ngDevMode ? [undefined, { debugName: "minOptionsHeight" }] : /* istanbul ignore next */ []));
5865
5897
  this.maxOptionsHeight = input('400px', ...(ngDevMode ? [{ debugName: "maxOptionsHeight" }] : /* istanbul ignore next */ []));
5866
5898
  this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
5899
+ /**
5900
+ * The control itself, which is only as wide as `width()`. The host element is a block element and
5901
+ * so can be considerably wider, and a click in that gap is an outside click.
5902
+ */
5903
+ this.wrapper = viewChild('wrapper', { ...(ngDevMode ? { debugName: "wrapper" } : /* istanbul ignore next */ {}), read: ElementRef });
5904
+ /** The options panel, `undefined` while it is closed since it only exists inside the cdk overlay */
5867
5905
  this.menuFilter = viewChild(FwMenuContainerComponent, ...(ngDevMode ? [{ debugName: "menuFilter" }] : /* istanbul ignore next */ []));
5868
5906
  // need this for the template
5869
5907
  this.createArray = (d) => Array.from(d);
@@ -5874,7 +5912,6 @@ class FwMultiSelectMenuComponent {
5874
5912
  this.focusedIndex = signal(0, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : /* istanbul ignore next */ []));
5875
5913
  this.touched = false;
5876
5914
  this.subscriptions = [];
5877
- this._isOpen = false;
5878
5915
  // eslint-disable-next-line @angular-eslint/no-output-native
5879
5916
  this.change = new EventEmitter();
5880
5917
  this.defaultFilter = (filter, menuItems) => {
@@ -5935,7 +5972,7 @@ class FwMultiSelectMenuComponent {
5935
5972
  /* eslint-enable */
5936
5973
  // needs to be an arrow function to lock the scope
5937
5974
  this.handleKeyDown = (event) => {
5938
- const handler = this.trigger.isOpen()
5975
+ const handler = this.isMenuOpen()
5939
5976
  ? this.keyboardActionMap[event.key]
5940
5977
  : this.closedTriggerKeyboardActionsMap[event.key];
5941
5978
  if (handler) {
@@ -5944,18 +5981,35 @@ class FwMultiSelectMenuComponent {
5944
5981
  }
5945
5982
  };
5946
5983
  }
5984
+ /**
5985
+ * Closes the options panel when a click lands outside of both the trigger and the panel.
5986
+ *
5987
+ * Registered by hand instead of through `@HostListener('document:click')` so that it runs in the
5988
+ * capture phase: a number of components in the library (`fw-menu-item`, `fw-chip`, `fw-navbar-item`,
5989
+ * the dialog backdrop, ...) call `stopPropagation()` on click, which would otherwise keep this
5990
+ * listener from ever seeing the click and leave the panel open.
5991
+ */
5947
5992
  outsideClick(event) {
5948
- if (this._isOpen) {
5949
- const clickedInside = this.elementRef.nativeElement.contains(event.target);
5950
- if (clickedInside) {
5951
- return;
5952
- }
5953
- this.trigger.close();
5954
- this._isOpen = false;
5955
- }
5956
- if (this.trigger && this.trigger.isOpen()) {
5957
- this._isOpen = true;
5993
+ if (!this.isMenuOpen() || this.isEventInsideSelect(event)) {
5994
+ return;
5958
5995
  }
5996
+ this.onTouched();
5997
+ this.trigger.close();
5998
+ }
5999
+ /**
6000
+ * Whether the options panel is currently open. The single place this class asks that question -
6001
+ * the trigger owns the state, so there is no local flag to keep in sync.
6002
+ *
6003
+ * ! Deliberately a plain method, not a `computed()` ! The trigger reports its state from the
6004
+ * overlay ref rather than from a signal, so a computed would memoize the first answer and stop
6005
+ * tracking, silently freezing `aria-expanded`.
6006
+ */
6007
+ isMenuOpen() {
6008
+ return this.trigger?.isOpen() ?? false;
6009
+ }
6010
+ /** Whether an event originated on this select's control box or inside its rendered options panel */
6011
+ isEventInsideSelect(event) {
6012
+ return isEventInside(event, this.wrapper()?.nativeElement, this.menuFilter()?.hostElement);
5959
6013
  }
5960
6014
  get value() {
5961
6015
  return this._value;
@@ -5978,7 +6032,11 @@ class FwMultiSelectMenuComponent {
5978
6032
  writeValue(value) {
5979
6033
  this.value = value;
5980
6034
  }
6035
+ ngOnInit() {
6036
+ this.document.addEventListener('click', this.documentClickListener, true);
6037
+ }
5981
6038
  ngOnDestroy() {
6039
+ this.document.removeEventListener('click', this.documentClickListener, true);
5982
6040
  for (const subscription of this.subscriptions) {
5983
6041
  subscription.unsubscribe();
5984
6042
  }
@@ -6117,13 +6175,13 @@ class FwMultiSelectMenuComponent {
6117
6175
  }
6118
6176
  }
6119
6177
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwMultiSelectMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6120
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FwMultiSelectMenuComponent, isStandalone: true, selector: "fw-multi-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, valueProperty: { classPropertyName: "valueProperty", publicName: "valueProperty", isSignal: true, isRequired: false, transformFunction: null }, titleProperty: { classPropertyName: "titleProperty", publicName: "titleProperty", isSignal: true, isRequired: false, transformFunction: null }, iconProperty: { classPropertyName: "iconProperty", publicName: "iconProperty", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, useCheckbox: { classPropertyName: "useCheckbox", publicName: "useCheckbox", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, maxSelectedShown: { classPropertyName: "maxSelectedShown", publicName: "maxSelectedShown", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showSelectionInfo: { classPropertyName: "showSelectionInfo", publicName: "showSelectionInfo", isSignal: true, isRequired: false, transformFunction: null }, filterItemsOnSelect: { classPropertyName: "filterItemsOnSelect", publicName: "filterItemsOnSelect", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, optionsWidth: { classPropertyName: "optionsWidth", publicName: "optionsWidth", isSignal: true, isRequired: false, transformFunction: null }, minOptionsHeight: { classPropertyName: "minOptionsHeight", publicName: "minOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, maxOptionsHeight: { classPropertyName: "maxOptionsHeight", publicName: "maxOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", change: "change" }, host: { listeners: { "document:click": "outsideClick($event)", "keydown": "handleKeyDown($event)" }, properties: { "tabIndex": "this.tabIndex", "class.disabled": "this.disabledClass" } }, providers: [
6178
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FwMultiSelectMenuComponent, isStandalone: true, selector: "fw-multi-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, valueProperty: { classPropertyName: "valueProperty", publicName: "valueProperty", isSignal: true, isRequired: false, transformFunction: null }, titleProperty: { classPropertyName: "titleProperty", publicName: "titleProperty", isSignal: true, isRequired: false, transformFunction: null }, iconProperty: { classPropertyName: "iconProperty", publicName: "iconProperty", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, useCheckbox: { classPropertyName: "useCheckbox", publicName: "useCheckbox", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, maxSelectedShown: { classPropertyName: "maxSelectedShown", publicName: "maxSelectedShown", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showSelectionInfo: { classPropertyName: "showSelectionInfo", publicName: "showSelectionInfo", isSignal: true, isRequired: false, transformFunction: null }, filterItemsOnSelect: { classPropertyName: "filterItemsOnSelect", publicName: "filterItemsOnSelect", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, optionsWidth: { classPropertyName: "optionsWidth", publicName: "optionsWidth", isSignal: true, isRequired: false, transformFunction: null }, minOptionsHeight: { classPropertyName: "minOptionsHeight", publicName: "minOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, maxOptionsHeight: { classPropertyName: "maxOptionsHeight", publicName: "maxOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", change: "change" }, host: { listeners: { "keydown": "handleKeyDown($event)" }, properties: { "tabIndex": "this.tabIndex", "class.disabled": "this.disabledClass" } }, providers: [
6121
6179
  {
6122
6180
  provide: NG_VALUE_ACCESSOR,
6123
6181
  useExisting: forwardRef(() => FwMultiSelectMenuComponent),
6124
6182
  multi: true,
6125
6183
  },
6126
- ], queries: [{ propertyName: "customMenuItems", predicate: FwMenuItemComponent, descendants: true }], viewQueries: [{ propertyName: "menuFilter", first: true, predicate: FwMenuContainerComponent, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: CdkMenuTrigger, descendants: true }, { propertyName: "menu", first: true, predicate: FwMenuComponent, descendants: true }, { propertyName: "renderedMenuItems", predicate: FwMenuItemComponent, descendants: true }], ngImport: i0, template: "<div [ngStyle]=\"{ width: width() }\" #wrapper>\n <div\n fwMenuRegister\n class=\"chip-grid\"\n [ngClass]=\"[size()]\"\n [ngStyle]=\"{ minHeight: minHeight(), maxHeight: maxHeight() }\"\n [cdkMenuTriggerFor]=\"selectMenu\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"trigger?.isOpen() || false\"\n [attr.aria-controls]=\"listboxId\"\n >\n @if (value.length === 0) {\n <span class=\"placeholder\">{{ placeholder() }}</span>\n }\n\n <!-- CHIPS -->\n @if (value && value.length > 0) {\n <div class=\"inner-chip-grid\">\n @for (chip of selectedOptions | slice: 0 : maxSelectedShown(); track chip) {\n <fw-chip\n [title]=\"chip[titleProperty()]\"\n [value]=\"chip[valueProperty()]\"\n [icon]=\"chip[iconProperty()]\"\n color=\"primary\"\n [showClose]=\"true\"\n (close)=\"handleChipClose(chip)\"\n [selectable]=\"false\"\n >\n </fw-chip>\n }\n @if (maxSelectedShown() === 0 && value.length > 0) {\n <span class=\"selected-text\"> {{ value.length }} selected </span>\n }\n @if (value.length > maxSelectedShown() && maxSelectedShown() > 0) {\n <span class=\"max-exceeded\"> +{{ value.length - maxSelectedShown() }} more </span>\n }\n </div>\n }\n\n @if (showClear() && value.length > 0) {\n <fw-icon (click)=\"updateValue([])\">close</fw-icon>\n }\n <fw-icon>chevron-down</fw-icon>\n </div>\n\n <!-- MENU -->\n <ng-template #selectMenu>\n <fw-menu-filter\n [keyHandler]=\"handleKeyDown\"\n [showFilter]=\"showFilter()\"\n [focusFilterOnMount]=\"showFilter()\"\n [width]=\"optionsWidth() || wrapper.offsetWidth - 2 + 'px'\"\n [additionalMenuItems]=\"this.customMenuItems.toArray()\"\n [emptyText]=\"emptyText()\"\n [maxHeight]=\"maxOptionsHeight()\"\n [minHeight]=\"minOptionsHeight()\"\n [filterFn]=\"filterFn()\"\n (filteredMenuItemChange)=\"displayedOptions.set($event)\"\n >\n @if (showSelectionInfo()) {\n <div class=\"filter-content\">\n <p>{{ value.length }} selections</p>\n <fw-button variant=\"ghost\" (click)=\"updateValue([])\">Clear</fw-button>\n </div>\n }\n <fw-menu\n role=\"listbox\"\n [id]=\"listboxId\"\n [multiSelect]=\"true\"\n [disabled]=\"disabled()\"\n [value]=\"createArray(selectedValues)\"\n (change)=\"handleMenuChange($event)\"\n >\n @if (customMenuItems.length === 0) {\n @for (item of options(); track item) {\n <fw-menu-item\n [title]=\"item[titleProperty()]\"\n [value]=\"item[valueProperty()]\"\n [icon]=\"item[iconProperty()]\"\n [multiSelect]=\"true\"\n [selected]=\"value.includes(item[valueProperty()])\"\n [showCheckbox]=\"useCheckbox()\"\n (mouseenter)=\"setFocusedIndex(item)\"\n >\n </fw-menu-item>\n }\n }\n <ng-content\n ngProjectAs=\"custom-menu-items\"\n select=\"[fw-menu-item, fw-menu-separator, fw-menu-item-group, fw-menu-header]\"\n ></ng-content>\n </fw-menu>\n </fw-menu-filter>\n </ng-template>\n</div>\n", styles: [":host{pointer-events:auto}:host.disabled{opacity:.4;cursor:not-allowed}:host.disabled>div{pointer-events:none}:host .placeholder{color:var(--typography-light);font-size:14px;padding-left:4px;text-wrap:nowrap;text-overflow:ellipsis;overflow:hidden}:host .chip-grid{min-height:36px;width:100%;box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;justify-content:space-between;padding:4px;align-items:center;border-radius:6px;overflow:hidden;border:1px solid var(--separations-input);cursor:pointer;font-family:Inter,sans-serif}:host .chip-grid.small{min-height:30px;padding:2px}:host .chip-grid.large{min-height:40px;padding:6px}:host .chip-grid:focus-within{border-color:var(--primary-base)}:host .chip-grid .inner-chip-grid{display:flex;flex-wrap:wrap;gap:4px;overflow:hidden auto;align-items:center;flex:1}:host .chip-grid .inner-chip-grid input{display:inline-flex;width:10px;flex-grow:1}:host .chip-grid fw-icon{font-size:20px}:host .chip-grid fw-icon:hover{color:var(--primary-base)}:host .chip-grid .selected-text{color:var(--typography-base);font-size:14px;padding:0 2px 0 4px;text-wrap:nowrap;text-overflow:ellipsis;overflow:hidden}:host .chip-grid .max-exceeded{font-size:12px}.filter-content{display:flex;align-items:center;justify-content:space-between;padding-left:4px;padding-top:4px}.filter-content p{color:var(--typography-muted);width:fit-content;margin:0}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: MenuRegisterDirective, selector: "[fwMenuRegister]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: FwChipComponent, selector: "fw-chip", inputs: ["maxWidth", "value", "variant", "color", "icon", "title", "description", "showClose", "closeLabel", "disabled", "selected", "textWrap", "selectable"], outputs: ["close", "select"] }, { kind: "component", type: FwIconComponent, selector: "fw-icon", inputs: ["ariaLabel", "size", "color"] }, { kind: "component", type: FwMenuContainerComponent, selector: "fw-menu-container, fw-menu-filter", inputs: ["width", "maxHeight", "minHeight", "border", "shadow", "showFilter", "filterText", "focusFilterOnMount", "offset", "emptyText", "filterFn", "additionalMenuItems", "additionalGroups", "additionalSeparators", "keyHandler"], outputs: ["filteredMenuItemChange", "filterChanged"] }, { kind: "component", type: FwButtonComponent, selector: "fw-button", inputs: ["color", "size", "variant", "type", "disabled", "fullWidth", "leftIcon", "rightIcon", "focusInitial"] }, { kind: "component", type: FwMenuComponent, selector: "fw-menu", inputs: ["disabled", "size", "multiSelect", "useCheckbox", "value", "role", "id"], outputs: ["disabledChange", "valueChange", "change"] }, { kind: "component", type: FwMenuItemComponent, selector: "fw-menu-item", inputs: ["itemRole", "value", "size", "title", "description", "icon", "iconColor", "disabled", "showCheckbox", "checkboxColor", "multiSelect", "hidden", "collapsed", "href", "target", "subItemsOpen", "mouseEnterHandler", "focused", "selected"], outputs: ["itemRoleChange", "sizeChange", "disabledChange", "showCheckboxChange", "multiSelectChange", "hiddenChange", "subItemsOpenChange", "mouseEnterHandlerChange", "click", "focusedChange", "selectedChange"] }, { kind: "pipe", type: SlicePipe, name: "slice" }] }); }
6184
+ ], queries: [{ propertyName: "customMenuItems", predicate: FwMenuItemComponent, descendants: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "menuFilter", first: true, predicate: FwMenuContainerComponent, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: CdkMenuTrigger, descendants: true }, { propertyName: "menu", first: true, predicate: FwMenuComponent, descendants: true }, { propertyName: "renderedMenuItems", predicate: FwMenuItemComponent, descendants: true }], ngImport: i0, template: "<div [ngStyle]=\"{ width: width() }\" #wrapper>\n <div\n fwMenuRegister\n class=\"chip-grid\"\n [ngClass]=\"[size()]\"\n [ngStyle]=\"{ minHeight: minHeight(), maxHeight: maxHeight() }\"\n [cdkMenuTriggerFor]=\"selectMenu\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"trigger?.isOpen() || false\"\n [attr.aria-controls]=\"listboxId\"\n >\n @if (value.length === 0) {\n <span class=\"placeholder\">{{ placeholder() }}</span>\n }\n\n <!-- CHIPS -->\n @if (value && value.length > 0) {\n <div class=\"inner-chip-grid\">\n @for (chip of selectedOptions | slice: 0 : maxSelectedShown(); track chip) {\n <fw-chip\n [title]=\"chip[titleProperty()]\"\n [value]=\"chip[valueProperty()]\"\n [icon]=\"chip[iconProperty()]\"\n color=\"primary\"\n [showClose]=\"true\"\n (close)=\"handleChipClose(chip)\"\n [selectable]=\"false\"\n >\n </fw-chip>\n }\n @if (maxSelectedShown() === 0 && value.length > 0) {\n <span class=\"selected-text\"> {{ value.length }} selected </span>\n }\n @if (value.length > maxSelectedShown() && maxSelectedShown() > 0) {\n <span class=\"max-exceeded\"> +{{ value.length - maxSelectedShown() }} more </span>\n }\n </div>\n }\n\n @if (showClear() && value.length > 0) {\n <fw-icon (click)=\"updateValue([])\">close</fw-icon>\n }\n <fw-icon>chevron-down</fw-icon>\n </div>\n\n <!-- MENU -->\n <ng-template #selectMenu>\n <fw-menu-filter\n [keyHandler]=\"handleKeyDown\"\n [showFilter]=\"showFilter()\"\n [focusFilterOnMount]=\"showFilter()\"\n [width]=\"optionsWidth() || wrapper.offsetWidth - 2 + 'px'\"\n [additionalMenuItems]=\"this.customMenuItems.toArray()\"\n [emptyText]=\"emptyText()\"\n [maxHeight]=\"maxOptionsHeight()\"\n [minHeight]=\"minOptionsHeight()\"\n [filterFn]=\"filterFn()\"\n (filteredMenuItemChange)=\"displayedOptions.set($event)\"\n >\n @if (showSelectionInfo()) {\n <div class=\"filter-content\">\n <p>{{ value.length }} selections</p>\n <fw-button variant=\"ghost\" (click)=\"updateValue([])\">Clear</fw-button>\n </div>\n }\n <fw-menu\n role=\"listbox\"\n [id]=\"listboxId\"\n [multiSelect]=\"true\"\n [disabled]=\"disabled()\"\n [value]=\"createArray(selectedValues)\"\n (change)=\"handleMenuChange($event)\"\n >\n @if (customMenuItems.length === 0) {\n @for (item of options(); track item) {\n <fw-menu-item\n [title]=\"item[titleProperty()]\"\n [value]=\"item[valueProperty()]\"\n [icon]=\"item[iconProperty()]\"\n [multiSelect]=\"true\"\n [selected]=\"value.includes(item[valueProperty()])\"\n [showCheckbox]=\"useCheckbox()\"\n (mouseenter)=\"setFocusedIndex(item)\"\n >\n </fw-menu-item>\n }\n }\n <ng-content\n ngProjectAs=\"custom-menu-items\"\n select=\"[fw-menu-item, fw-menu-separator, fw-menu-item-group, fw-menu-header]\"\n ></ng-content>\n </fw-menu>\n </fw-menu-filter>\n </ng-template>\n</div>\n", styles: [":host{pointer-events:auto}:host.disabled{opacity:.4;cursor:not-allowed}:host.disabled>div{pointer-events:none}:host .placeholder{color:var(--typography-light);font-size:14px;padding-left:4px;text-wrap:nowrap;text-overflow:ellipsis;overflow:hidden}:host .chip-grid{min-height:36px;width:100%;box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;justify-content:space-between;padding:4px;align-items:center;border-radius:6px;overflow:hidden;border:1px solid var(--separations-input);cursor:pointer;font-family:Inter,sans-serif}:host .chip-grid.small{min-height:30px;padding:2px}:host .chip-grid.large{min-height:40px;padding:6px}:host .chip-grid:focus-within{border-color:var(--primary-base)}:host .chip-grid .inner-chip-grid{display:flex;flex-wrap:wrap;gap:4px;overflow:hidden auto;align-items:center;flex:1}:host .chip-grid .inner-chip-grid input{display:inline-flex;width:10px;flex-grow:1}:host .chip-grid fw-icon{font-size:20px}:host .chip-grid fw-icon:hover{color:var(--primary-base)}:host .chip-grid .selected-text{color:var(--typography-base);font-size:14px;padding:0 2px 0 4px;text-wrap:nowrap;text-overflow:ellipsis;overflow:hidden}:host .chip-grid .max-exceeded{font-size:12px}.filter-content{display:flex;align-items:center;justify-content:space-between;padding-left:4px;padding-top:4px}.filter-content p{color:var(--typography-muted);width:fit-content;margin:0}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: MenuRegisterDirective, selector: "[fwMenuRegister]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: FwChipComponent, selector: "fw-chip", inputs: ["maxWidth", "value", "variant", "color", "icon", "title", "description", "showClose", "closeLabel", "disabled", "selected", "textWrap", "selectable"], outputs: ["close", "select"] }, { kind: "component", type: FwIconComponent, selector: "fw-icon", inputs: ["ariaLabel", "size", "color"] }, { kind: "component", type: FwMenuContainerComponent, selector: "fw-menu-container, fw-menu-filter", inputs: ["width", "maxHeight", "minHeight", "border", "shadow", "showFilter", "filterText", "focusFilterOnMount", "offset", "emptyText", "filterFn", "additionalMenuItems", "additionalGroups", "additionalSeparators", "keyHandler"], outputs: ["filteredMenuItemChange", "filterChanged"] }, { kind: "component", type: FwButtonComponent, selector: "fw-button", inputs: ["color", "size", "variant", "type", "disabled", "fullWidth", "leftIcon", "rightIcon", "focusInitial"] }, { kind: "component", type: FwMenuComponent, selector: "fw-menu", inputs: ["disabled", "size", "multiSelect", "useCheckbox", "value", "role", "id"], outputs: ["disabledChange", "valueChange", "change"] }, { kind: "component", type: FwMenuItemComponent, selector: "fw-menu-item", inputs: ["itemRole", "value", "size", "title", "description", "icon", "iconColor", "disabled", "showCheckbox", "checkboxColor", "multiSelect", "hidden", "collapsed", "href", "target", "subItemsOpen", "mouseEnterHandler", "focused", "selected"], outputs: ["itemRoleChange", "sizeChange", "disabledChange", "showCheckboxChange", "multiSelectChange", "hiddenChange", "subItemsOpenChange", "mouseEnterHandlerChange", "click", "focusedChange", "selectedChange"] }, { kind: "pipe", type: SlicePipe, name: "slice" }] }); }
6127
6185
  }
6128
6186
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwMultiSelectMenuComponent, decorators: [{
6129
6187
  type: Component,
@@ -6146,16 +6204,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
6146
6204
  FwMenuItemComponent,
6147
6205
  SlicePipe,
6148
6206
  ], template: "<div [ngStyle]=\"{ width: width() }\" #wrapper>\n <div\n fwMenuRegister\n class=\"chip-grid\"\n [ngClass]=\"[size()]\"\n [ngStyle]=\"{ minHeight: minHeight(), maxHeight: maxHeight() }\"\n [cdkMenuTriggerFor]=\"selectMenu\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"trigger?.isOpen() || false\"\n [attr.aria-controls]=\"listboxId\"\n >\n @if (value.length === 0) {\n <span class=\"placeholder\">{{ placeholder() }}</span>\n }\n\n <!-- CHIPS -->\n @if (value && value.length > 0) {\n <div class=\"inner-chip-grid\">\n @for (chip of selectedOptions | slice: 0 : maxSelectedShown(); track chip) {\n <fw-chip\n [title]=\"chip[titleProperty()]\"\n [value]=\"chip[valueProperty()]\"\n [icon]=\"chip[iconProperty()]\"\n color=\"primary\"\n [showClose]=\"true\"\n (close)=\"handleChipClose(chip)\"\n [selectable]=\"false\"\n >\n </fw-chip>\n }\n @if (maxSelectedShown() === 0 && value.length > 0) {\n <span class=\"selected-text\"> {{ value.length }} selected </span>\n }\n @if (value.length > maxSelectedShown() && maxSelectedShown() > 0) {\n <span class=\"max-exceeded\"> +{{ value.length - maxSelectedShown() }} more </span>\n }\n </div>\n }\n\n @if (showClear() && value.length > 0) {\n <fw-icon (click)=\"updateValue([])\">close</fw-icon>\n }\n <fw-icon>chevron-down</fw-icon>\n </div>\n\n <!-- MENU -->\n <ng-template #selectMenu>\n <fw-menu-filter\n [keyHandler]=\"handleKeyDown\"\n [showFilter]=\"showFilter()\"\n [focusFilterOnMount]=\"showFilter()\"\n [width]=\"optionsWidth() || wrapper.offsetWidth - 2 + 'px'\"\n [additionalMenuItems]=\"this.customMenuItems.toArray()\"\n [emptyText]=\"emptyText()\"\n [maxHeight]=\"maxOptionsHeight()\"\n [minHeight]=\"minOptionsHeight()\"\n [filterFn]=\"filterFn()\"\n (filteredMenuItemChange)=\"displayedOptions.set($event)\"\n >\n @if (showSelectionInfo()) {\n <div class=\"filter-content\">\n <p>{{ value.length }} selections</p>\n <fw-button variant=\"ghost\" (click)=\"updateValue([])\">Clear</fw-button>\n </div>\n }\n <fw-menu\n role=\"listbox\"\n [id]=\"listboxId\"\n [multiSelect]=\"true\"\n [disabled]=\"disabled()\"\n [value]=\"createArray(selectedValues)\"\n (change)=\"handleMenuChange($event)\"\n >\n @if (customMenuItems.length === 0) {\n @for (item of options(); track item) {\n <fw-menu-item\n [title]=\"item[titleProperty()]\"\n [value]=\"item[valueProperty()]\"\n [icon]=\"item[iconProperty()]\"\n [multiSelect]=\"true\"\n [selected]=\"value.includes(item[valueProperty()])\"\n [showCheckbox]=\"useCheckbox()\"\n (mouseenter)=\"setFocusedIndex(item)\"\n >\n </fw-menu-item>\n }\n }\n <ng-content\n ngProjectAs=\"custom-menu-items\"\n select=\"[fw-menu-item, fw-menu-separator, fw-menu-item-group, fw-menu-header]\"\n ></ng-content>\n </fw-menu>\n </fw-menu-filter>\n </ng-template>\n</div>\n", styles: [":host{pointer-events:auto}:host.disabled{opacity:.4;cursor:not-allowed}:host.disabled>div{pointer-events:none}:host .placeholder{color:var(--typography-light);font-size:14px;padding-left:4px;text-wrap:nowrap;text-overflow:ellipsis;overflow:hidden}:host .chip-grid{min-height:36px;width:100%;box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;justify-content:space-between;padding:4px;align-items:center;border-radius:6px;overflow:hidden;border:1px solid var(--separations-input);cursor:pointer;font-family:Inter,sans-serif}:host .chip-grid.small{min-height:30px;padding:2px}:host .chip-grid.large{min-height:40px;padding:6px}:host .chip-grid:focus-within{border-color:var(--primary-base)}:host .chip-grid .inner-chip-grid{display:flex;flex-wrap:wrap;gap:4px;overflow:hidden auto;align-items:center;flex:1}:host .chip-grid .inner-chip-grid input{display:inline-flex;width:10px;flex-grow:1}:host .chip-grid fw-icon{font-size:20px}:host .chip-grid fw-icon:hover{color:var(--primary-base)}:host .chip-grid .selected-text{color:var(--typography-base);font-size:14px;padding:0 2px 0 4px;text-wrap:nowrap;text-overflow:ellipsis;overflow:hidden}:host .chip-grid .max-exceeded{font-size:12px}.filter-content{display:flex;align-items:center;justify-content:space-between;padding-left:4px;padding-top:4px}.filter-content p{color:var(--typography-muted);width:fit-content;margin:0}\n"] }]
6149
- }], propDecorators: { outsideClick: [{
6150
- type: HostListener,
6151
- args: ['document:click', ['$event']]
6152
- }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], valueProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueProperty", required: false }] }], titleProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleProperty", required: false }] }], iconProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconProperty", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], useCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "useCheckbox", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], maxSelectedShown: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelectedShown", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], showSelectionInfo: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelectionInfo", required: false }] }], filterItemsOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterItemsOnSelect", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], optionsWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionsWidth", required: false }] }], minOptionsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minOptionsHeight", required: false }] }], maxOptionsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxOptionsHeight", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], trigger: [{
6207
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], valueProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueProperty", required: false }] }], titleProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleProperty", required: false }] }], iconProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconProperty", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], useCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "useCheckbox", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], maxSelectedShown: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelectedShown", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], showSelectionInfo: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelectionInfo", required: false }] }], filterItemsOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterItemsOnSelect", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], optionsWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionsWidth", required: false }] }], minOptionsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minOptionsHeight", required: false }] }], maxOptionsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxOptionsHeight", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], trigger: [{
6153
6208
  type: ViewChild,
6154
6209
  args: [CdkMenuTrigger]
6155
6210
  }], menu: [{
6156
6211
  type: ViewChild,
6157
6212
  args: [FwMenuComponent]
6158
- }], menuFilter: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FwMenuContainerComponent), { isSignal: true }] }], renderedMenuItems: [{
6213
+ }], wrapper: [{ type: i0.ViewChild, args: ['wrapper', { ...{ read: ElementRef }, isSignal: true }] }], menuFilter: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FwMenuContainerComponent), { isSignal: true }] }], renderedMenuItems: [{
6159
6214
  type: ViewChildren,
6160
6215
  args: [FwMenuItemComponent]
6161
6216
  }], customMenuItems: [{
@@ -6182,28 +6237,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
6182
6237
  * @see [Vision storybook](https://cdn.flywheel.io/docs/vision/master/?path=/docs/form-controls-select--docs)
6183
6238
  */
6184
6239
  class FwSelectMenuComponent {
6185
- outsideClick(evt) {
6186
- // Check if click is inside the overlay (menu items) but NOT on the input trigger
6187
- const clickedElement = evt.target;
6188
- const overlayPane = clickedElement.closest('.cdk-overlay-pane');
6189
- const clickedInsideOverlay = overlayPane && !clickedElement.closest('fw-text-input');
6190
- // Don't process outside clicks when clicking on menu items (but not the trigger input)
6191
- if (clickedInsideOverlay) {
6240
+ /**
6241
+ * Closes the options panel when a click lands outside of both the trigger and the panel.
6242
+ *
6243
+ * Registered by hand instead of through `@HostListener('document:click')` so that it runs in the
6244
+ * capture phase: a number of components in the library (`fw-menu-item`, `fw-chip`, `fw-navbar-item`,
6245
+ * the dialog backdrop, ...) call `stopPropagation()` on click, which would otherwise keep this
6246
+ * listener from ever seeing the click and leave the panel open.
6247
+ */
6248
+ outsideClick(event) {
6249
+ if (!this.isMenuOpen() || this.isEventInsideSelect(event)) {
6192
6250
  return;
6193
6251
  }
6194
- if (this._isOpen && evt.target.nodeName !== 'INPUT') {
6195
- this.onTouched();
6196
- this.close();
6197
- this._isOpen = false;
6198
- }
6199
- // Sync _isOpen state with actual trigger state
6200
- if (this.trigger && this.trigger.isOpen()) {
6201
- this._isOpen = true;
6202
- }
6203
- else {
6204
- this._isOpen = false;
6252
+ // Typing moves `selectValue` onto the highlighted match without committing it, so a dismissed
6253
+ // filter has to be rolled back or the input ends up displaying an option that was never picked
6254
+ const hadUncommittedFilter = this.isTyping();
6255
+ this.onTouched();
6256
+ this.close();
6257
+ this.inFocusOpen = false;
6258
+ if (hadUncommittedFilter) {
6259
+ this.selectValue.set(this.displayValueOnOpen);
6260
+ this.selectTitle.set(this.displayTitleOnOpen);
6261
+ this.updateHighlighting();
6205
6262
  }
6206
6263
  }
6264
+ /** Whether an event originated on this select's control box or inside its rendered options panel */
6265
+ isEventInsideSelect(event) {
6266
+ return isEventInside(event, this.wrapper()?.nativeElement, this.panel()?.hostElement);
6267
+ }
6207
6268
  get disabledClass() {
6208
6269
  return this.disabled();
6209
6270
  }
@@ -6218,7 +6279,9 @@ class FwSelectMenuComponent {
6218
6279
  }
6219
6280
  constructor() {
6220
6281
  this.ngControl = inject(NgControl, { optional: true, self: true });
6282
+ this.document = inject(DOCUMENT);
6221
6283
  this.listboxId = inject(_IdGenerator).getId('fw-select-listbox-');
6284
+ this.documentClickListener = (event) => this.outsideClick(event);
6222
6285
  this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
6223
6286
  this.valueProperty = input('value', ...(ngDevMode ? [{ debugName: "valueProperty" }] : /* istanbul ignore next */ []));
6224
6287
  this.useFullOptionAsValue = input(false, ...(ngDevMode ? [{ debugName: "useFullOptionAsValue" }] : /* istanbul ignore next */ []));
@@ -6237,6 +6300,13 @@ class FwSelectMenuComponent {
6237
6300
  this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
6238
6301
  this.placeholder = input('Select something...', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
6239
6302
  this.menu = viewChild(FwMenuComponent, ...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
6303
+ /**
6304
+ * The control itself, which is only as wide as `width()`. The host element is a block element and
6305
+ * so can be considerably wider, and a click in that gap is an outside click.
6306
+ */
6307
+ this.wrapper = viewChild('wrapper', { ...(ngDevMode ? { debugName: "wrapper" } : /* istanbul ignore next */ {}), read: ElementRef });
6308
+ /** The options panel, `undefined` while it is closed since it only exists inside the cdk overlay */
6309
+ this.panel = viewChild(FwMenuContainerComponent, ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
6240
6310
  this.menuItems = contentChildren(FwMenuItemComponent, { ...(ngDevMode ? { debugName: "menuItems" } : /* istanbul ignore next */ {}), descendants: true });
6241
6311
  this.viewMenuItems = viewChildren(FwMenuItemComponent, ...(ngDevMode ? [{ debugName: "viewMenuItems" }] : /* istanbul ignore next */ []));
6242
6312
  this.menuItemGroups = contentChildren(FwMenuItemGroupComponent, { ...(ngDevMode ? { debugName: "menuItemGroups" } : /* istanbul ignore next */ {}), descendants: true });
@@ -6248,9 +6318,11 @@ class FwSelectMenuComponent {
6248
6318
  this.filterValue = signal('', ...(ngDevMode ? [{ debugName: "filterValue" }] : /* istanbul ignore next */ []));
6249
6319
  this.menuItemClickSubscriptions = [];
6250
6320
  this.subscriptions = [];
6251
- this._isOpen = false;
6252
6321
  this.focused = 0;
6253
6322
  this.inFocusOpen = false;
6323
+ /** Displayed value and title as of the last time the panel was opened, used to undo a dismissed filter */
6324
+ this.displayValueOnOpen = '';
6325
+ this.displayTitleOnOpen = '';
6254
6326
  this.isTyping = signal(false, ...(ngDevMode ? [{ debugName: "isTyping" }] : /* istanbul ignore next */ []));
6255
6327
  this.valueDisplayFn = input((menuItem) => menuItem.title() || '', ...(ngDevMode ? [{ debugName: "valueDisplayFn" }] : /* istanbul ignore next */ []));
6256
6328
  this.defaultFilterFn = (filter, items) => items.filter((item) => {
@@ -6331,11 +6403,14 @@ class FwSelectMenuComponent {
6331
6403
  }
6332
6404
  }
6333
6405
  ngOnInit() {
6406
+ this.document.addEventListener('click', this.documentClickListener, true);
6334
6407
  const onOpenSub = this.trigger.opened.subscribe(() => {
6335
6408
  // Initialize navigation state synchronously so the first arrow key press
6336
6409
  // navigates relative to the selected item rather than being swallowed by setup
6337
6410
  this.inFocusOpen = true;
6338
6411
  this.preFocusValue = this.value;
6412
+ this.displayValueOnOpen = this.selectValue();
6413
+ this.displayTitleOnOpen = this.selectTitle();
6339
6414
  this.initializeFocusedIndex();
6340
6415
  const currentValue = this.selectValue();
6341
6416
  setTimeout(() => {
@@ -6371,6 +6446,7 @@ class FwSelectMenuComponent {
6371
6446
  }
6372
6447
  }
6373
6448
  ngOnDestroy() {
6449
+ this.document.removeEventListener('click', this.documentClickListener, true);
6374
6450
  this.menuItemClickSubscriptions.forEach((sub) => sub.unsubscribe());
6375
6451
  this.subscriptions.forEach((sub) => sub.unsubscribe());
6376
6452
  }
@@ -6418,14 +6494,22 @@ class FwSelectMenuComponent {
6418
6494
  this.close();
6419
6495
  this.inFocusOpen = false;
6420
6496
  }
6497
+ /**
6498
+ * Whether the options panel is currently open. The single place this class asks that question -
6499
+ * the trigger owns the state, so there is no local flag to keep in sync.
6500
+ *
6501
+ * ! Deliberately a plain method, not a `computed()` ! The trigger reports its state from the
6502
+ * overlay ref rather than from a signal, so a computed would memoize the first answer and stop
6503
+ * tracking, silently freezing `aria-expanded`.
6504
+ */
6421
6505
  isMenuOpen() {
6422
- return this.trigger.isOpen();
6506
+ return this.trigger?.isOpen() ?? false;
6423
6507
  }
6424
6508
  /**
6425
6509
  * The DOM id of the currently active/highlighted option, for aria-activedescendant on the combobox input.
6426
6510
  */
6427
6511
  getActiveDescendantId() {
6428
- if (!this.trigger.isOpen()) {
6512
+ if (!this.isMenuOpen()) {
6429
6513
  return undefined;
6430
6514
  }
6431
6515
  const availableItems = this.getAvailableItems();
@@ -6446,7 +6530,7 @@ class FwSelectMenuComponent {
6446
6530
  getAvailableItems() {
6447
6531
  // If using options input, return filtered options excluding disabled ones
6448
6532
  if (this.options().length > 0) {
6449
- return this.filteredOptions().filter(opt => !opt['disabled']);
6533
+ return this.filteredOptions().filter((opt) => !opt['disabled']);
6450
6534
  }
6451
6535
  // If using content projection, filter by typeahead text and exclude disabled items
6452
6536
  if (this.menuItems().length > 0) {
@@ -6589,7 +6673,6 @@ class FwSelectMenuComponent {
6589
6673
  if (hasSelection) {
6590
6674
  this.isTyping.set(true);
6591
6675
  this.trigger.open();
6592
- this._isOpen = true;
6593
6676
  this.inFocusOpen = true;
6594
6677
  this.preFocusValue = this.value;
6595
6678
  this.initializeFocusedIndex();
@@ -6615,7 +6698,7 @@ class FwSelectMenuComponent {
6615
6698
  'PageDown',
6616
6699
  'Delete',
6617
6700
  ].includes(event.key);
6618
- if (!this.trigger.isOpen() &&
6701
+ if (!this.isMenuOpen() &&
6619
6702
  !this.isTyping() &&
6620
6703
  this.selectTitle() &&
6621
6704
  event.key.length === 1 &&
@@ -6627,7 +6710,6 @@ class FwSelectMenuComponent {
6627
6710
  // Just switch to typing mode and the input event will update filterValue
6628
6711
  this.isTyping.set(true);
6629
6712
  this.trigger.open();
6630
- this._isOpen = true;
6631
6713
  this.inFocusOpen = true;
6632
6714
  this.preFocusValue = this.value;
6633
6715
  this.initializeFocusedIndex();
@@ -6640,7 +6722,7 @@ class FwSelectMenuComponent {
6640
6722
  // Let default behavior happen, onInputChange will handle it
6641
6723
  return;
6642
6724
  }
6643
- if (this.trigger.isOpen()) {
6725
+ if (this.isMenuOpen()) {
6644
6726
  if (this.inFocusOpen) {
6645
6727
  if (event.key === 'ArrowDown') {
6646
6728
  event.preventDefault();
@@ -6752,7 +6834,7 @@ class FwSelectMenuComponent {
6752
6834
  }
6753
6835
  }
6754
6836
  handleKeyUp(event) {
6755
- if (this.trigger.isOpen()) {
6837
+ if (this.isMenuOpen()) {
6756
6838
  if (event.key === 'Escape') {
6757
6839
  this.isTyping.set(false);
6758
6840
  this.close();
@@ -6824,7 +6906,6 @@ class FwSelectMenuComponent {
6824
6906
  this.trigger.close();
6825
6907
  this.filterValue.set('');
6826
6908
  this.filterChanged.emit(this.filterValue());
6827
- this._isOpen = false;
6828
6909
  this.isTyping.set(false);
6829
6910
  }
6830
6911
  onFilterChanged(value) {
@@ -6878,13 +6959,12 @@ class FwSelectMenuComponent {
6878
6959
  }, 0);
6879
6960
  this.filterChanged.emit(this.filterValue());
6880
6961
  // Auto-open dropdown when user starts typing
6881
- if (this.filterValue() && !this.trigger.isOpen()) {
6962
+ if (this.filterValue() && !this.isMenuOpen()) {
6882
6963
  this.trigger.open();
6883
- this._isOpen = true;
6884
6964
  }
6885
6965
  }
6886
6966
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwSelectMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6887
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FwSelectMenuComponent, isStandalone: true, selector: "fw-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, valueProperty: { classPropertyName: "valueProperty", publicName: "valueProperty", isSignal: true, isRequired: false, transformFunction: null }, useFullOptionAsValue: { classPropertyName: "useFullOptionAsValue", publicName: "useFullOptionAsValue", isSignal: true, isRequired: false, transformFunction: null }, titleProperty: { classPropertyName: "titleProperty", publicName: "titleProperty", isSignal: true, isRequired: false, transformFunction: null }, iconProperty: { classPropertyName: "iconProperty", publicName: "iconProperty", isSignal: true, isRequired: false, transformFunction: null }, staticIcon: { classPropertyName: "staticIcon", publicName: "staticIcon", isSignal: true, isRequired: false, transformFunction: null }, descriptionProperty: { classPropertyName: "descriptionProperty", publicName: "descriptionProperty", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showReset: { classPropertyName: "showReset", publicName: "showReset", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errored: { classPropertyName: "errored", publicName: "errored", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, optionsWidth: { classPropertyName: "optionsWidth", publicName: "optionsWidth", isSignal: true, isRequired: false, transformFunction: null }, minOptionsHeight: { classPropertyName: "minOptionsHeight", publicName: "minOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, maxOptionsHeight: { classPropertyName: "maxOptionsHeight", publicName: "maxOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, valueDisplayFn: { classPropertyName: "valueDisplayFn", publicName: "valueDisplayFn", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", change: "change", filterChanged: "filterChanged" }, host: { listeners: { "document:click": "outsideClick($event)" }, properties: { "class.disabled": "this.disabledClass" } }, queries: [{ propertyName: "menuItems", predicate: FwMenuItemComponent, descendants: true, isSignal: true }, { propertyName: "menuItemGroups", predicate: FwMenuItemGroupComponent, descendants: true, isSignal: true }, { propertyName: "menuSeparators", predicate: FwMenuSeparatorComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "menu", first: true, predicate: FwMenuComponent, descendants: true, isSignal: true }, { propertyName: "viewMenuItems", predicate: FwMenuItemComponent, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: CdkMenuTrigger, descendants: true, static: true }, { propertyName: "textInput", first: true, predicate: FwTextInputComponent, descendants: true }], ngImport: i0, template: "<div #wrapper [style.width]=\"width()\">\n <fw-text-input\n fwMenuRegister\n [cdkMenuTriggerFor]=\"selectMenu\"\n [value]=\"inputDisplayValue()\"\n [leftIcon]=\"staticIcon() || selectIcon || null\"\n [rightIcon]=\"(selectTitle()&&showReset())?'close-circled':'chevron-down'\"\n (rightIconAction)=\"handleReset()\"\n [useActionableIcons]=\"true\"\n [placeholder]=\"placeholder()\"\n [size]=\"size()\"\n [error]=\"errored() || (invalid && touched)\"\n (input)=\"onInputChange($event)\"\n (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\"\n (focus)=\"handleFocus()\"\n (click)=\"handleInputClick()\"\n [readOnly]=\"false\"\n role=\"combobox\"\n [ariaExpanded]=\"isMenuOpen()\"\n [ariaControls]=\"listboxId\"\n ariaAutocomplete=\"list\"\n [ariaActiveDescendant]=\"getActiveDescendantId()\">\n </fw-text-input>\n <ng-template #selectMenu>\n @if (!disabled()) {\n <fw-menu-container\n [filterFn]=\"filterFn()\"\n [filterText]=\"filterValue()\"\n [additionalMenuItems]=\"menuItems()\"\n [additionalGroups]=\"menuItemGroups()\"\n [additionalSeparators]=\"menuSeparators()\"\n [showFilter]=\"showFilter()\" [width]=\"optionsWidth() || wrapper.offsetWidth + 'px'\"\n [maxHeight]=\"maxOptionsHeight()\" [minHeight]=\"minOptionsHeight()\" (filterChanged)=\"onFilterChanged($event)\">\n <fw-menu\n role=\"listbox\"\n [id]=\"listboxId\"\n [disabled]=\"disabled()\"\n [value]=\"selectValue()\"\n (change)=\"handleClick($any($event))\"\n >\n @if (menuItems().length === 0) {\n @for (item of optionsWithValues(); track item.trackingId) {\n <fw-menu-item\n [title]=\"item.raw[titleProperty()]?.toString()\"\n [description]=\"$any(item.raw[descriptionProperty()])\"\n [value]=\"item.value\"\n [icon]=\"$any(item.raw[iconProperty()])\"\n [disabled]=\"$any(item.raw).disabled\"\n />\n }\n }\n <div #menuContentWrapper>\n <ng-content select=\"[fw-menu-item, fw-menu-separator, fw-menu-item-group]\"></ng-content>\n </div>\n </fw-menu>\n </fw-menu-container>\n }\n </ng-template>\n</div>\n", styles: [":host{box-sizing:border-box;max-width:100%}:host>div{cursor:pointer}:host.disabled{opacity:.4;cursor:not-allowed}:host.disabled>div{pointer-events:none}\n"], dependencies: [{ kind: "component", type: FwTextInputComponent, selector: "fw-text-input", inputs: ["disabled", "useActionableIcons", "leftIcon", "rightIcon", "leftIconLabel", "rightIconLabel", "prefix", "context", "ariaLabel", "required", "role", "ariaExpanded", "ariaControls", "ariaAutocomplete", "ariaActiveDescendant", "helperText", "errorText", "errorInIconTooltip", "placeholder", "readOnly", "size", "type", "maxLength", "autofocus", "autocomplete", "value", "error", "width"], outputs: ["disabledChange", "leftIconAction", "rightIconAction"] }, { kind: "directive", type: MenuRegisterDirective, selector: "[fwMenuRegister]" }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: FwMenuContainerComponent, selector: "fw-menu-container, fw-menu-filter", inputs: ["width", "maxHeight", "minHeight", "border", "shadow", "showFilter", "filterText", "focusFilterOnMount", "offset", "emptyText", "filterFn", "additionalMenuItems", "additionalGroups", "additionalSeparators", "keyHandler"], outputs: ["filteredMenuItemChange", "filterChanged"] }, { kind: "component", type: FwMenuComponent, selector: "fw-menu", inputs: ["disabled", "size", "multiSelect", "useCheckbox", "value", "role", "id"], outputs: ["disabledChange", "valueChange", "change"] }, { kind: "component", type: FwMenuItemComponent, selector: "fw-menu-item", inputs: ["itemRole", "value", "size", "title", "description", "icon", "iconColor", "disabled", "showCheckbox", "checkboxColor", "multiSelect", "hidden", "collapsed", "href", "target", "subItemsOpen", "mouseEnterHandler", "focused", "selected"], outputs: ["itemRoleChange", "sizeChange", "disabledChange", "showCheckboxChange", "multiSelectChange", "hiddenChange", "subItemsOpenChange", "mouseEnterHandlerChange", "click", "focusedChange", "selectedChange"] }] }); }
6967
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FwSelectMenuComponent, isStandalone: true, selector: "fw-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, valueProperty: { classPropertyName: "valueProperty", publicName: "valueProperty", isSignal: true, isRequired: false, transformFunction: null }, useFullOptionAsValue: { classPropertyName: "useFullOptionAsValue", publicName: "useFullOptionAsValue", isSignal: true, isRequired: false, transformFunction: null }, titleProperty: { classPropertyName: "titleProperty", publicName: "titleProperty", isSignal: true, isRequired: false, transformFunction: null }, iconProperty: { classPropertyName: "iconProperty", publicName: "iconProperty", isSignal: true, isRequired: false, transformFunction: null }, staticIcon: { classPropertyName: "staticIcon", publicName: "staticIcon", isSignal: true, isRequired: false, transformFunction: null }, descriptionProperty: { classPropertyName: "descriptionProperty", publicName: "descriptionProperty", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showReset: { classPropertyName: "showReset", publicName: "showReset", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errored: { classPropertyName: "errored", publicName: "errored", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, optionsWidth: { classPropertyName: "optionsWidth", publicName: "optionsWidth", isSignal: true, isRequired: false, transformFunction: null }, minOptionsHeight: { classPropertyName: "minOptionsHeight", publicName: "minOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, maxOptionsHeight: { classPropertyName: "maxOptionsHeight", publicName: "maxOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, valueDisplayFn: { classPropertyName: "valueDisplayFn", publicName: "valueDisplayFn", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", change: "change", filterChanged: "filterChanged" }, host: { properties: { "class.disabled": "this.disabledClass" } }, queries: [{ propertyName: "menuItems", predicate: FwMenuItemComponent, descendants: true, isSignal: true }, { propertyName: "menuItemGroups", predicate: FwMenuItemGroupComponent, descendants: true, isSignal: true }, { propertyName: "menuSeparators", predicate: FwMenuSeparatorComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "menu", first: true, predicate: FwMenuComponent, descendants: true, isSignal: true }, { propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "panel", first: true, predicate: FwMenuContainerComponent, descendants: true, isSignal: true }, { propertyName: "viewMenuItems", predicate: FwMenuItemComponent, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: CdkMenuTrigger, descendants: true, static: true }, { propertyName: "textInput", first: true, predicate: FwTextInputComponent, descendants: true }], ngImport: i0, template: "<div #wrapper [style.width]=\"width()\">\n <fw-text-input\n fwMenuRegister\n [cdkMenuTriggerFor]=\"selectMenu\"\n [value]=\"inputDisplayValue()\"\n [leftIcon]=\"staticIcon() || selectIcon || null\"\n [rightIcon]=\"(selectTitle()&&showReset())?'close-circled':'chevron-down'\"\n (rightIconAction)=\"handleReset()\"\n [useActionableIcons]=\"true\"\n [placeholder]=\"placeholder()\"\n [size]=\"size()\"\n [error]=\"errored() || (invalid && touched)\"\n (input)=\"onInputChange($event)\"\n (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\"\n (focus)=\"handleFocus()\"\n (click)=\"handleInputClick()\"\n [readOnly]=\"false\"\n role=\"combobox\"\n [ariaExpanded]=\"isMenuOpen()\"\n [ariaControls]=\"listboxId\"\n ariaAutocomplete=\"list\"\n [ariaActiveDescendant]=\"getActiveDescendantId()\">\n </fw-text-input>\n <ng-template #selectMenu>\n @if (!disabled()) {\n <fw-menu-container\n [filterFn]=\"filterFn()\"\n [filterText]=\"filterValue()\"\n [additionalMenuItems]=\"menuItems()\"\n [additionalGroups]=\"menuItemGroups()\"\n [additionalSeparators]=\"menuSeparators()\"\n [showFilter]=\"showFilter()\" [width]=\"optionsWidth() || wrapper.offsetWidth + 'px'\"\n [maxHeight]=\"maxOptionsHeight()\" [minHeight]=\"minOptionsHeight()\" (filterChanged)=\"onFilterChanged($event)\">\n <fw-menu\n role=\"listbox\"\n [id]=\"listboxId\"\n [disabled]=\"disabled()\"\n [value]=\"selectValue()\"\n (change)=\"handleClick($any($event))\"\n >\n @if (menuItems().length === 0) {\n @for (item of optionsWithValues(); track item.trackingId) {\n <fw-menu-item\n [title]=\"item.raw[titleProperty()]?.toString()\"\n [description]=\"$any(item.raw[descriptionProperty()])\"\n [value]=\"item.value\"\n [icon]=\"$any(item.raw[iconProperty()])\"\n [disabled]=\"$any(item.raw).disabled\"\n />\n }\n }\n <div #menuContentWrapper>\n <ng-content select=\"[fw-menu-item, fw-menu-separator, fw-menu-item-group]\"></ng-content>\n </div>\n </fw-menu>\n </fw-menu-container>\n }\n </ng-template>\n</div>\n", styles: [":host{box-sizing:border-box;max-width:100%}:host>div{cursor:pointer}:host.disabled{opacity:.4;cursor:not-allowed}:host.disabled>div{pointer-events:none}\n"], dependencies: [{ kind: "component", type: FwTextInputComponent, selector: "fw-text-input", inputs: ["disabled", "useActionableIcons", "leftIcon", "rightIcon", "leftIconLabel", "rightIconLabel", "prefix", "context", "ariaLabel", "required", "role", "ariaExpanded", "ariaControls", "ariaAutocomplete", "ariaActiveDescendant", "helperText", "errorText", "errorInIconTooltip", "placeholder", "readOnly", "size", "type", "maxLength", "autofocus", "autocomplete", "value", "error", "width"], outputs: ["disabledChange", "leftIconAction", "rightIconAction"] }, { kind: "directive", type: MenuRegisterDirective, selector: "[fwMenuRegister]" }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: FwMenuContainerComponent, selector: "fw-menu-container, fw-menu-filter", inputs: ["width", "maxHeight", "minHeight", "border", "shadow", "showFilter", "filterText", "focusFilterOnMount", "offset", "emptyText", "filterFn", "additionalMenuItems", "additionalGroups", "additionalSeparators", "keyHandler"], outputs: ["filteredMenuItemChange", "filterChanged"] }, { kind: "component", type: FwMenuComponent, selector: "fw-menu", inputs: ["disabled", "size", "multiSelect", "useCheckbox", "value", "role", "id"], outputs: ["disabledChange", "valueChange", "change"] }, { kind: "component", type: FwMenuItemComponent, selector: "fw-menu-item", inputs: ["itemRole", "value", "size", "title", "description", "icon", "iconColor", "disabled", "showCheckbox", "checkboxColor", "multiSelect", "hidden", "collapsed", "href", "target", "subItemsOpen", "mouseEnterHandler", "focused", "selected"], outputs: ["itemRoleChange", "sizeChange", "disabledChange", "showCheckboxChange", "multiSelectChange", "hiddenChange", "subItemsOpenChange", "mouseEnterHandlerChange", "click", "focusedChange", "selectedChange"] }] }); }
6888
6968
  }
6889
6969
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwSelectMenuComponent, decorators: [{
6890
6970
  type: Component,
@@ -6896,10 +6976,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
6896
6976
  FwMenuComponent,
6897
6977
  FwMenuItemComponent,
6898
6978
  ], template: "<div #wrapper [style.width]=\"width()\">\n <fw-text-input\n fwMenuRegister\n [cdkMenuTriggerFor]=\"selectMenu\"\n [value]=\"inputDisplayValue()\"\n [leftIcon]=\"staticIcon() || selectIcon || null\"\n [rightIcon]=\"(selectTitle()&&showReset())?'close-circled':'chevron-down'\"\n (rightIconAction)=\"handleReset()\"\n [useActionableIcons]=\"true\"\n [placeholder]=\"placeholder()\"\n [size]=\"size()\"\n [error]=\"errored() || (invalid && touched)\"\n (input)=\"onInputChange($event)\"\n (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\"\n (focus)=\"handleFocus()\"\n (click)=\"handleInputClick()\"\n [readOnly]=\"false\"\n role=\"combobox\"\n [ariaExpanded]=\"isMenuOpen()\"\n [ariaControls]=\"listboxId\"\n ariaAutocomplete=\"list\"\n [ariaActiveDescendant]=\"getActiveDescendantId()\">\n </fw-text-input>\n <ng-template #selectMenu>\n @if (!disabled()) {\n <fw-menu-container\n [filterFn]=\"filterFn()\"\n [filterText]=\"filterValue()\"\n [additionalMenuItems]=\"menuItems()\"\n [additionalGroups]=\"menuItemGroups()\"\n [additionalSeparators]=\"menuSeparators()\"\n [showFilter]=\"showFilter()\" [width]=\"optionsWidth() || wrapper.offsetWidth + 'px'\"\n [maxHeight]=\"maxOptionsHeight()\" [minHeight]=\"minOptionsHeight()\" (filterChanged)=\"onFilterChanged($event)\">\n <fw-menu\n role=\"listbox\"\n [id]=\"listboxId\"\n [disabled]=\"disabled()\"\n [value]=\"selectValue()\"\n (change)=\"handleClick($any($event))\"\n >\n @if (menuItems().length === 0) {\n @for (item of optionsWithValues(); track item.trackingId) {\n <fw-menu-item\n [title]=\"item.raw[titleProperty()]?.toString()\"\n [description]=\"$any(item.raw[descriptionProperty()])\"\n [value]=\"item.value\"\n [icon]=\"$any(item.raw[iconProperty()])\"\n [disabled]=\"$any(item.raw).disabled\"\n />\n }\n }\n <div #menuContentWrapper>\n <ng-content select=\"[fw-menu-item, fw-menu-separator, fw-menu-item-group]\"></ng-content>\n </div>\n </fw-menu>\n </fw-menu-container>\n }\n </ng-template>\n</div>\n", styles: [":host{box-sizing:border-box;max-width:100%}:host>div{cursor:pointer}:host.disabled{opacity:.4;cursor:not-allowed}:host.disabled>div{pointer-events:none}\n"] }]
6899
- }], ctorParameters: () => [], propDecorators: { outsideClick: [{
6900
- type: HostListener,
6901
- args: ['document:click', ['$event']]
6902
- }], disabledClass: [{
6979
+ }], ctorParameters: () => [], propDecorators: { disabledClass: [{
6903
6980
  type: HostBinding,
6904
6981
  args: ['class.disabled']
6905
6982
  }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], valueProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueProperty", required: false }] }], useFullOptionAsValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "useFullOptionAsValue", required: false }] }], titleProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleProperty", required: false }] }], iconProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconProperty", required: false }] }], staticIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "staticIcon", required: false }] }], descriptionProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "descriptionProperty", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], showReset: [{ type: i0.Input, args: [{ isSignal: true, alias: "showReset", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], errored: [{ type: i0.Input, args: [{ isSignal: true, alias: "errored", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], optionsWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionsWidth", required: false }] }], minOptionsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minOptionsHeight", required: false }] }], maxOptionsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxOptionsHeight", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], trigger: [{
@@ -6908,7 +6985,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
6908
6985
  }], textInput: [{
6909
6986
  type: ViewChild,
6910
6987
  args: [FwTextInputComponent]
6911
- }], menu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FwMenuComponent), { isSignal: true }] }], menuItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FwMenuItemComponent), { ...{ descendants: true }, isSignal: true }] }], viewMenuItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => FwMenuItemComponent), { isSignal: true }] }], menuItemGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FwMenuItemGroupComponent), { ...{ descendants: true }, isSignal: true }] }], menuSeparators: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FwMenuSeparatorComponent), { ...{ descendants: true }, isSignal: true }] }], change: [{
6988
+ }], menu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FwMenuComponent), { isSignal: true }] }], wrapper: [{ type: i0.ViewChild, args: ['wrapper', { ...{ read: ElementRef }, isSignal: true }] }], panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FwMenuContainerComponent), { isSignal: true }] }], menuItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FwMenuItemComponent), { ...{ descendants: true }, isSignal: true }] }], viewMenuItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => FwMenuItemComponent), { isSignal: true }] }], menuItemGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FwMenuItemGroupComponent), { ...{ descendants: true }, isSignal: true }] }], menuSeparators: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FwMenuSeparatorComponent), { ...{ descendants: true }, isSignal: true }] }], change: [{
6912
6989
  type: Output
6913
6990
  }], filterChanged: [{
6914
6991
  type: Output