@flywheel-io/vision 2.4.5 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { HostBinding, Input, ChangeDetectionStrategy, Component, EventEmitter, Output, NgModule, input, model, computed, ContentChildren, ViewChild, ViewEncapsulation, Directive, forwardRef, HostListener, Optional, Inject, SkipSelf, Injectable, Pipe, ContentChild, signal, effect, inject, ChangeDetectorRef, output, contentChildren, Host, viewChild, ViewChildren, Self } from '@angular/core';
2
+ import { HostBinding, Input, ChangeDetectionStrategy, Component, EventEmitter, Output, NgModule, input, model, computed, ContentChildren, ViewChild, ViewEncapsulation, Directive, forwardRef, HostListener, Optional, Inject, SkipSelf, Injectable, Pipe, ContentChild, signal, effect, inject, ChangeDetectorRef, output, contentChildren, Host, viewChild, ViewChildren, Self, ElementRef, viewChildren } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
4
+ import { CommonModule, NgClass } from '@angular/common';
5
5
  import * as i1 from '@angular/platform-browser';
6
6
  import * as i8 from '@angular/forms';
7
7
  import { NG_VALUE_ACCESSOR, ReactiveFormsModule, FormsModule } from '@angular/forms';
@@ -9,7 +9,7 @@ import * as i1$2 from '@angular/cdk/dialog';
9
9
  import { Dialog, DEFAULT_DIALOG_CONFIG, DIALOG_SCROLL_STRATEGY, DialogModule } from '@angular/cdk/dialog';
10
10
  import * as i1$3 from '@angular/cdk/overlay';
11
11
  import { OverlayModule, Overlay } from '@angular/cdk/overlay';
12
- import { of, BehaviorSubject, Subscription, min } from 'rxjs';
12
+ import { of, BehaviorSubject, Subscription, min, startWith, tap, switchMap, map } from 'rxjs';
13
13
  import { parseISO, isBefore, isSameDay, isAfter } from 'date-fns';
14
14
  import { isValidPhoneNumber, getExampleNumber, parsePhoneNumberFromString, AsYouType } from 'libphonenumber-js';
15
15
  import { trigger, state, transition, style, animate } from '@angular/animations';
@@ -22,6 +22,7 @@ export { CdkTableModule } from '@angular/cdk/table';
22
22
  import { _DisposeViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY } from '@angular/cdk/collections';
23
23
  import * as i2 from '@angular/cdk/text-field';
24
24
  import { CdkTextareaAutosize, TextFieldModule } from '@angular/cdk/text-field';
25
+ import { toObservable, toSignal } from '@angular/core/rxjs-interop';
25
26
 
26
27
  class FwIconComponent {
27
28
  get style() {
@@ -4216,7 +4217,7 @@ class FwPopoverComponent {
4216
4217
  };
4217
4218
  this.registerEventListeners = effect(() => {
4218
4219
  const trigger = this.trigger();
4219
- if (!this.trigger) {
4220
+ if (!trigger) {
4220
4221
  return;
4221
4222
  }
4222
4223
  if (this.action === 'mouseenter' && !trigger.onmouseenter) {
@@ -5225,7 +5226,7 @@ class FwPaginatorComponent {
5225
5226
  this.selectorTitle = 'Items per page:';
5226
5227
  this.page = new EventEmitter();
5227
5228
  this.pages = [];
5228
- this.pagesTrackByFn = (index, page) => page.pageIndex;
5229
+ this.pagesTrackByFn = (_, page) => page.pageIndex;
5229
5230
  }
5230
5231
  ngOnChanges(changes) {
5231
5232
  if (changes.pageIndex || changes.maxPagesShown || changes.length || changes.pageSize) {
@@ -5470,7 +5471,7 @@ class FwMultiSelectMenuComponent {
5470
5471
  this.displayedOptions().forEach((item, index) => {
5471
5472
  item.focused = index === this.focusedIndex();
5472
5473
  });
5473
- });
5474
+ }, { allowSignalWrites: true });
5474
5475
  /* eslint-disable @typescript-eslint/naming-convention, @rx-angular/prefer-no-layout-sensitive-apis */
5475
5476
  this.keyboardActionMap = {
5476
5477
  'ArrowDown': () => {
@@ -5554,7 +5555,7 @@ class FwMultiSelectMenuComponent {
5554
5555
  icon: newMenuItem.icon,
5555
5556
  };
5556
5557
  this.options.push(newOption);
5557
- newMenuItem.mouseEnterHandler.set((event, item) => {
5558
+ newMenuItem.mouseEnterHandler.set((_, item) => {
5558
5559
  this.setFocusedIndex(item);
5559
5560
  });
5560
5561
  // add click listener
@@ -8426,16 +8427,294 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
8426
8427
  }]
8427
8428
  }] });
8428
8429
 
8430
+ // the nature of this component is to handle a complex layout issue so disabling this lint rule
8431
+ /* eslint-disable @rx-angular/prefer-no-layout-sensitive-apis */
8432
+ class FwChipListComponent {
8433
+ constructor() {
8434
+ this.changeDetector = inject(ChangeDetectorRef);
8435
+ this.hostElement = inject(ElementRef);
8436
+ this.childChipElementRefs = contentChildren(FwChipComponent, { read: ElementRef });
8437
+ this.moreText = viewChild.required('moreText');
8438
+ this.hiddenElementCount = signal(0);
8439
+ this.hiddenChips = signal([]);
8440
+ this.hiddenLabels = computed(() => {
8441
+ return this.hiddenChips().map(chip => {
8442
+ // this relies on the dom shape of the chip, might be fragile
8443
+ const contentSpan = chip.querySelector('span');
8444
+ return contentSpan.innerText;
8445
+ }).join(', ');
8446
+ });
8447
+ this.childrenChanged = effect(() => {
8448
+ this.childChipElementRefs();
8449
+ this.calcChipOverflow();
8450
+ }, { allowSignalWrites: true });
8451
+ this.resizeObserver = new ResizeObserver(() => {
8452
+ this.calcChipOverflow();
8453
+ });
8454
+ }
8455
+ ngOnInit() {
8456
+ this.resizeObserver.observe(this.hostElement.nativeElement);
8457
+ }
8458
+ calcChipOverflow() {
8459
+ const hostRect = this.hostElement.nativeElement.getBoundingClientRect();
8460
+ const chipElements = this.childChipElementRefs().map(ref => ref.nativeElement);
8461
+ const moreTextElement = this.moreText().nativeElement;
8462
+ chipElements.forEach(chip => chip.classList.remove('hidden'));
8463
+ moreTextElement.classList.remove('hidden');
8464
+ const visibleChips = chipElements.filter(chip => {
8465
+ const chipRect = chip.getBoundingClientRect();
8466
+ return !(chipRect.right > hostRect.right || chipRect.bottom > hostRect.bottom);
8467
+ });
8468
+ const overflowChips = chipElements.toSpliced(0, visibleChips.length);
8469
+ if (overflowChips.length > 0) {
8470
+ const lastVisibleChip = visibleChips[visibleChips.length - 1];
8471
+ const enoughRoomForMoreText = (hostRect.right - lastVisibleChip.getBoundingClientRect().right) > (moreTextElement.offsetWidth);
8472
+ if (!enoughRoomForMoreText) {
8473
+ overflowChips.push(lastVisibleChip);
8474
+ }
8475
+ this.hiddenChips.set(overflowChips);
8476
+ overflowChips.forEach(hiddenChip => {
8477
+ hiddenChip.classList.add('hidden');
8478
+ });
8479
+ }
8480
+ else {
8481
+ this.moreText().nativeElement.classList.add('hidden');
8482
+ }
8483
+ this.changeDetector.detectChanges();
8484
+ }
8485
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FwChipListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8486
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: FwChipListComponent, isStandalone: true, selector: "fw-chip-list", queries: [{ propertyName: "childChipElementRefs", predicate: FwChipComponent, read: ElementRef, isSignal: true }], viewQueries: [{ propertyName: "moreText", first: true, predicate: ["moreText"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\n<fw-tooltip [title]=\"hiddenLabels()\">\n <p #moreText> +{{hiddenChips().length}} more </p>\n</fw-tooltip>\n", styles: [":host{flex-basis:max-content;display:flex;flex-flow:row wrap;gap:8px;align-items:flex-start;justify-content:flex-start;max-height:28px;overflow:hidden}:host p{line-height:24px;cursor:default;margin:0 8px 0 0;text-wrap:nowrap;color:var(--typography-muted)}:host::ng-deep .hidden{display:none}\n"], dependencies: [{ kind: "ngmodule", type: FwChipModule }, { kind: "ngmodule", type: FwTooltipModule }, { kind: "component", type: FwTooltipComponent, selector: "fw-tooltip", inputs: ["title", "color", "position", "maxWidth", "fullWidth", "isOpen", "trigger", "delay"] }] }); }
8487
+ }
8488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FwChipListComponent, decorators: [{
8489
+ type: Component,
8490
+ args: [{ selector: 'fw-chip-list', standalone: true, imports: [
8491
+ FwChipModule,
8492
+ FwTooltipModule,
8493
+ ], template: "<ng-content></ng-content>\n<fw-tooltip [title]=\"hiddenLabels()\">\n <p #moreText> +{{hiddenChips().length}} more </p>\n</fw-tooltip>\n", styles: [":host{flex-basis:max-content;display:flex;flex-flow:row wrap;gap:8px;align-items:flex-start;justify-content:flex-start;max-height:28px;overflow:hidden}:host p{line-height:24px;cursor:default;margin:0 8px 0 0;text-wrap:nowrap;color:var(--typography-muted)}:host::ng-deep .hidden{display:none}\n"] }]
8494
+ }] });
8495
+
8496
+ /**
8497
+ * Component for having a user select multiple values while also allowing arbitrary values to be added
8498
+ * @see [Vision Docs](https://cdn.flywheel.io/docs/vision/master/?path=/docs/form-controls-typeahead--docs)
8499
+ */
8500
+ class FwTypeaheadComponent {
8501
+ constructor() {
8502
+ this.trigger = viewChild(CdkMenuTrigger);
8503
+ this.changeDetector = inject(ChangeDetectorRef);
8504
+ this.loading = model(false);
8505
+ this.disabled = model(false);
8506
+ this.onChange = (_) => { };
8507
+ this.onTouched = () => { };
8508
+ this.value = model([]);
8509
+ this.optionsInput = input([], { alias: 'options' });
8510
+ this.maxOptionsHeight = input('400px');
8511
+ this.minOptionsHeight = input('0px');
8512
+ this.optionsWidth = input('');
8513
+ this.notifyOnValueChanges = effect(() => {
8514
+ this.onChange(this.value());
8515
+ });
8516
+ this.searchValue = model('');
8517
+ this.searchValueChanges$ = toObservable(this.searchValue);
8518
+ this.allowNew = input(true);
8519
+ this.placeholder = input('Enter tags...');
8520
+ this.options$ = this.searchValueChanges$.pipe(startWith(''), tap(() => this.loading.set(true)), switchMap(searchString => {
8521
+ if (typeof this.optionsInput() === 'function') {
8522
+ const fetchingFunction = this.optionsInput();
8523
+ return fetchingFunction(searchString);
8524
+ }
8525
+ const filteredStaticOptions$ = of(this.optionsInput()).pipe(map(options => options.filter(opt => opt.toLowerCase().includes(searchString.toLowerCase()))));
8526
+ return filteredStaticOptions$;
8527
+ }), map(options => {
8528
+ return options.filter(option => {
8529
+ const alreadySelected = this.value().find(val => val.toLowerCase() === option.toLowerCase());
8530
+ return !alreadySelected;
8531
+ });
8532
+ }), tap(() => this.loading.set(false)));
8533
+ this.optionsSignal = toSignal(this.options$);
8534
+ this.displayNewOption = computed(() => {
8535
+ const newValue = this.searchValue();
8536
+ if (!newValue) {
8537
+ return false;
8538
+ }
8539
+ const directMatch = this.optionsSignal()?.includes?.(newValue);
8540
+ const loading = this.loading();
8541
+ const alreadySelected = Boolean(this.value().find(val => val.toLowerCase() === newValue.toLowerCase()));
8542
+ return this.allowNew() && !alreadySelected && (!directMatch || loading);
8543
+ });
8544
+ this.addValue = (newValue) => {
8545
+ this.value.update(prevValue => [
8546
+ ...prevValue || [],
8547
+ newValue,
8548
+ ]);
8549
+ };
8550
+ this.handleOptionClick = (optionValue) => {
8551
+ this.onTouched();
8552
+ this.addValue(optionValue);
8553
+ this.focusInput();
8554
+ this.searchValue.set('');
8555
+ };
8556
+ this.resetFocusOnOptionsChange = effect(() => {
8557
+ if (this.displayedOptions() || this.searchValue()) {
8558
+ this.focusedIndex.set(0);
8559
+ }
8560
+ }, { allowSignalWrites: true });
8561
+ this.displayedOptions = viewChildren(FwMenuItemComponent);
8562
+ this.focusedIndex = signal(0);
8563
+ this.focusedOption = computed(() => {
8564
+ const options = this.displayedOptions();
8565
+ const focused = this.focusedIndex();
8566
+ const onlyOne = options.length === 1;
8567
+ return onlyOne ? this.searchValue() : options[focused]?.value;
8568
+ });
8569
+ this.inputRef = viewChild.required('input');
8570
+ /* eslint-disable @typescript-eslint/naming-convention */
8571
+ this.keyHandlerMap = {
8572
+ 'Enter': () => {
8573
+ this.onTouched();
8574
+ const newValue = this.focusedOption() || this.searchValue();
8575
+ const duplicate = this.value().find(val => val.toLowerCase() === newValue.toLowerCase());
8576
+ if (!newValue || duplicate) {
8577
+ return;
8578
+ }
8579
+ this.addValue(newValue);
8580
+ this.searchValue.set('');
8581
+ },
8582
+ 'ArrowDown': () => {
8583
+ this.moveFocused('down');
8584
+ },
8585
+ 'ArrowUp': () => {
8586
+ this.moveFocused('up');
8587
+ },
8588
+ 'Backspace': () => {
8589
+ const searchIsEmpty = !this.searchValue(); // any falsy value is empty
8590
+ if (searchIsEmpty && this.value()?.length > 0) {
8591
+ this.closeChip(this.value()[this.value().length - 1]);
8592
+ }
8593
+ return !searchIsEmpty;
8594
+ },
8595
+ 'Tab': () => {
8596
+ if (this.trigger().isOpen) {
8597
+ this.trigger().close();
8598
+ }
8599
+ },
8600
+ };
8601
+ }
8602
+ outsideClick() {
8603
+ this.onTouched();
8604
+ this.trigger().close();
8605
+ }
8606
+ setDisabledState(isDisabled) {
8607
+ this.disabled.set(isDisabled);
8608
+ }
8609
+ writeValue(incomingValue) {
8610
+ this.value.set(incomingValue);
8611
+ }
8612
+ registerOnChange(onChangeFn) {
8613
+ this.onChange = onChangeFn;
8614
+ }
8615
+ registerOnTouched(onTouchedFn) {
8616
+ this.onTouched = onTouchedFn;
8617
+ }
8618
+ onClick(event) {
8619
+ event.preventDefault();
8620
+ event.stopPropagation();
8621
+ }
8622
+ handleSearchChange(event) {
8623
+ if (this.trigger().closed) {
8624
+ this.trigger().open();
8625
+ }
8626
+ const value = event.target.value;
8627
+ this.searchValue.set(value);
8628
+ }
8629
+ closeChip(chipValue) {
8630
+ const currentValue = this.value();
8631
+ const newValue = currentValue.filter(val => val !== chipValue);
8632
+ this.value.set(newValue);
8633
+ this.focusInput();
8634
+ this.changeDetector.detectChanges();
8635
+ }
8636
+ focusInput(e = null) {
8637
+ e?.preventDefault();
8638
+ e?.stopPropagation();
8639
+ e?.stopImmediatePropagation();
8640
+ this.inputRef().nativeElement.focus();
8641
+ }
8642
+ /* eslint-enable */
8643
+ handleKey(e) {
8644
+ const handler = this.keyHandlerMap[e.key];
8645
+ handler?.(e);
8646
+ }
8647
+ setFocusByValue(value) {
8648
+ const options = this.displayedOptions();
8649
+ const foundIndex = options.findIndex(opt => opt.value === value);
8650
+ const finalIndex = foundIndex === -1 ? 0 : foundIndex;
8651
+ this.focusedIndex.set(finalIndex);
8652
+ }
8653
+ moveFocused(direction) {
8654
+ const options = this.displayedOptions();
8655
+ const index = this.focusedIndex();
8656
+ const clampIndex = (n) => {
8657
+ if (n < 0) {
8658
+ return options.length - 1;
8659
+ }
8660
+ else if (n >= options.length) {
8661
+ return 0;
8662
+ }
8663
+ return n;
8664
+ };
8665
+ const indexChange = direction === 'up' ? -1 : 1;
8666
+ const newIndex = clampIndex(index + indexChange);
8667
+ this.focusedIndex.set(newIndex);
8668
+ const newlyFocused = this.displayedOptions()[this.focusedIndex()];
8669
+ // eslint-disable-next-line @rx-angular/prefer-no-layout-sensitive-apis
8670
+ newlyFocused.scrollIntoView();
8671
+ }
8672
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FwTypeaheadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8673
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: FwTypeaheadComponent, isStandalone: true, selector: "fw-typeahead", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, optionsInput: { classPropertyName: "optionsInput", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, maxOptionsHeight: { classPropertyName: "maxOptionsHeight", publicName: "maxOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, minOptionsHeight: { classPropertyName: "minOptionsHeight", publicName: "minOptionsHeight", isSignal: true, isRequired: false, transformFunction: null }, optionsWidth: { classPropertyName: "optionsWidth", publicName: "optionsWidth", isSignal: true, isRequired: false, transformFunction: null }, searchValue: { classPropertyName: "searchValue", publicName: "searchValue", isSignal: true, isRequired: false, transformFunction: null }, allowNew: { classPropertyName: "allowNew", publicName: "allowNew", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loading: "loadingChange", disabled: "disabledChange", value: "valueChange", searchValue: "searchValueChange" }, host: { listeners: { "document:click": "outsideClick()", "click": "onClick($event)" } }, providers: [
8674
+ {
8675
+ provide: NG_VALUE_ACCESSOR,
8676
+ useExisting: forwardRef(() => FwTypeaheadComponent),
8677
+ multi: true,
8678
+ },
8679
+ ], viewQueries: [{ propertyName: "trigger", first: true, predicate: CdkMenuTrigger, descendants: true, isSignal: true }, { propertyName: "displayedOptions", predicate: FwMenuItemComponent, descendants: true, isSignal: true }, { propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n (click)=\"focusInput($event)\"\n class=\"input-container\"\n [ngClass]=\"{ 'disabled': disabled() }\"\n [cdkMenuTriggerFor]=\"menuContent\"\n fwMenuRegister\n #inputContainer>\n <fw-chip-list class=\"chips\">\n @for(val of value(); track val) {\n <fw-chip\n color=\"primary\"\n [showClose]=\"true\"\n [title]=\"val\"\n [selectable]=\"false\"\n (close)=\"closeChip(val)\"\n />\n }\n </fw-chip-list>\n <input\n test-id=\"typeahead-input\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [value]=\"searchValue()\"\n (keyup)=\"handleSearchChange($event)\"\n (keydown)=\"handleKey($event)\"\n #input\n type=\"text\"\n />\n @if(loading()) {\n <fw-progress-spinner size=\"small\"/>\n }\n</div>\n<ng-template #menuContent>\n <fw-menu-container\n [maxHeight]=\"maxOptionsHeight()\"\n [minHeight]=\"minOptionsHeight()\"\n [width]=\"optionsWidth() || inputContainer.offsetWidth - 2 + 'px'\"\n >\n <fw-menu>\n @if(loading() && !displayNewOption()) {\n <fw-menu-item title=\"Searching...\" [disabled]=\"true\"/>\n } @else if(!loading()) {\n @for (option of optionsSignal(); track option) {\n <fw-menu-item\n (click)=\"handleOptionClick($event)\"\n (mouseenter)=\"setFocusByValue(option)\"\n [title]=\"option\"\n [focused]=\"focusedOption() === option\"\n [value]=\"option\"\n />\n }\n @empty {\n @if (!displayNewOption()) {\n <fw-menu-item title=\"No tag suggestions\" [disabled]=\"true\"/>\n }\n }\n }\n @if(displayNewOption()) {\n <fw-menu-item\n (click)=\"handleOptionClick($event)\"\n (mouseenter)=\"setFocusByValue(searchValue())\"\n [title]=\"searchValue()\"\n [value]=\"searchValue()\"\n [focused]=\"focusedOption() === searchValue()\">\n <p class=\"new-tag\">New</p>\n </fw-menu-item>\n }\n </fw-menu>\n </fw-menu-container>\n</ng-template>\n", styles: [".new-tag{margin:0;color:var(--typography-light)}:host{display:flex;flex-direction:column;width:100%;line-height:21px}:host.disabled{cursor:not-allowed}:host.disabled fw-icon{cursor:not-allowed!important}:host .chips,:host fw-progress-spinner{margin:-4px 0}:host .input-container{width:100%;box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;padding:8px;align-items:center;border-radius:6px;border:1px solid var(--separations-input);font-family:Inter,sans-serif}:host .input-container:focus-within{border:1px solid var(--primary-base)}:host .input-container input{min-width:80px;font-size:14px;flex:1 1 80px;color:var(--typography-base);background:var(--page-light);border:none}:host .input-container input:focus{outline:none;border:none}:host .input-container input::placeholder{color:var(--typography-light)}:host .input-container .context{color:var(--typography-light)}:host.errored .input-container,:host.ng-touched.ng-invalid .input-container{border:1px solid var(--red-base)}.disabled{opacity:.4;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: FwTextInputModule }, { kind: "ngmodule", type: FwChipModule }, { kind: "component", type: FwChipComponent, selector: "fw-chip", inputs: ["value", "variant", "color", "icon", "title", "description", "showClose", "disabled", "selected", "selectable"], outputs: ["close", "select"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FwMenuModule }, { kind: "component", type: FwMenuComponent, selector: "fw-menu", inputs: ["disabled", "size", "multiSelect", "useCheckbox", "value"], outputs: ["change"] }, { kind: "component", type: FwMenuContainerComponent, selector: "fw-menu-container, fw-menu-filter", inputs: ["width", "maxHeight", "minHeight", "border", "shadow", "showFilter", "filterText", "focusFilterOnMount", "offset", "emptyText", "filterFn", "additionalMenuItems", "keyHandler"], outputs: ["filteredMenuItemChange", "filterChanged"] }, { kind: "component", type: FwMenuItemComponent, selector: "fw-menu-item", inputs: ["value", "size", "title", "description", "icon", "iconColor", "disabled", "showCheckbox", "checkboxColor", "multiSelect", "hidden", "collapsed", "href", "target", "subItemsOpen", "mouseEnterHandler", "focused", "selected"], outputs: ["mouseEnterHandlerChange", "click"] }, { kind: "ngmodule", type: CdkMenuModule }, { kind: "directive", type: i1$4.CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "directive", type: MenuRegisterDirective, selector: "[fwMenuRegister]" }, { kind: "ngmodule", type: FwProgressModule }, { kind: "component", type: FwProgressSpinnerComponent, selector: "fw-progress-spinner", inputs: ["mode", "size", "color", "showValue", "value"] }, { kind: "component", type: FwChipListComponent, selector: "fw-chip-list" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
8680
+ }
8681
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FwTypeaheadComponent, decorators: [{
8682
+ type: Component,
8683
+ args: [{ selector: 'fw-typeahead', standalone: true, imports: [
8684
+ FwTextInputModule,
8685
+ FwChipModule,
8686
+ ReactiveFormsModule,
8687
+ FwMenuModule,
8688
+ CdkMenuModule,
8689
+ MenuRegisterDirective,
8690
+ FwProgressModule,
8691
+ FwChipListComponent,
8692
+ NgClass,
8693
+ ], providers: [
8694
+ {
8695
+ provide: NG_VALUE_ACCESSOR,
8696
+ useExisting: forwardRef(() => FwTypeaheadComponent),
8697
+ multi: true,
8698
+ },
8699
+ ], template: "<div\n (click)=\"focusInput($event)\"\n class=\"input-container\"\n [ngClass]=\"{ 'disabled': disabled() }\"\n [cdkMenuTriggerFor]=\"menuContent\"\n fwMenuRegister\n #inputContainer>\n <fw-chip-list class=\"chips\">\n @for(val of value(); track val) {\n <fw-chip\n color=\"primary\"\n [showClose]=\"true\"\n [title]=\"val\"\n [selectable]=\"false\"\n (close)=\"closeChip(val)\"\n />\n }\n </fw-chip-list>\n <input\n test-id=\"typeahead-input\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [value]=\"searchValue()\"\n (keyup)=\"handleSearchChange($event)\"\n (keydown)=\"handleKey($event)\"\n #input\n type=\"text\"\n />\n @if(loading()) {\n <fw-progress-spinner size=\"small\"/>\n }\n</div>\n<ng-template #menuContent>\n <fw-menu-container\n [maxHeight]=\"maxOptionsHeight()\"\n [minHeight]=\"minOptionsHeight()\"\n [width]=\"optionsWidth() || inputContainer.offsetWidth - 2 + 'px'\"\n >\n <fw-menu>\n @if(loading() && !displayNewOption()) {\n <fw-menu-item title=\"Searching...\" [disabled]=\"true\"/>\n } @else if(!loading()) {\n @for (option of optionsSignal(); track option) {\n <fw-menu-item\n (click)=\"handleOptionClick($event)\"\n (mouseenter)=\"setFocusByValue(option)\"\n [title]=\"option\"\n [focused]=\"focusedOption() === option\"\n [value]=\"option\"\n />\n }\n @empty {\n @if (!displayNewOption()) {\n <fw-menu-item title=\"No tag suggestions\" [disabled]=\"true\"/>\n }\n }\n }\n @if(displayNewOption()) {\n <fw-menu-item\n (click)=\"handleOptionClick($event)\"\n (mouseenter)=\"setFocusByValue(searchValue())\"\n [title]=\"searchValue()\"\n [value]=\"searchValue()\"\n [focused]=\"focusedOption() === searchValue()\">\n <p class=\"new-tag\">New</p>\n </fw-menu-item>\n }\n </fw-menu>\n </fw-menu-container>\n</ng-template>\n", styles: [".new-tag{margin:0;color:var(--typography-light)}:host{display:flex;flex-direction:column;width:100%;line-height:21px}:host.disabled{cursor:not-allowed}:host.disabled fw-icon{cursor:not-allowed!important}:host .chips,:host fw-progress-spinner{margin:-4px 0}:host .input-container{width:100%;box-sizing:border-box;color:var(--typography-light);background:var(--page-light);display:flex;padding:8px;align-items:center;border-radius:6px;border:1px solid var(--separations-input);font-family:Inter,sans-serif}:host .input-container:focus-within{border:1px solid var(--primary-base)}:host .input-container input{min-width:80px;font-size:14px;flex:1 1 80px;color:var(--typography-base);background:var(--page-light);border:none}:host .input-container input:focus{outline:none;border:none}:host .input-container input::placeholder{color:var(--typography-light)}:host .input-container .context{color:var(--typography-light)}:host.errored .input-container,:host.ng-touched.ng-invalid .input-container{border:1px solid var(--red-base)}.disabled{opacity:.4;pointer-events:none}\n"] }]
8700
+ }], propDecorators: { outsideClick: [{
8701
+ type: HostListener,
8702
+ args: ['document:click']
8703
+ }], onClick: [{
8704
+ type: HostListener,
8705
+ args: ['click', ['$event']]
8706
+ }] } });
8707
+
8429
8708
  class FwWrappedInputComponent {
8430
8709
  constructor() {
8431
8710
  this.class = true;
8432
8711
  }
8433
8712
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FwWrappedInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8434
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FwWrappedInputComponent, selector: "fw-wrapped-input", inputs: { title: "title", description: "description", helperText: "helperText", errorText: "errorText" }, host: { properties: { "class.fw-wrapped-input": "this.class" } }, ngImport: i0, template: "<label>\n <fw-form-heading *ngIf=\"title\" [title]=\"title\" [description]=\"description\"></fw-form-heading>\n <ng-content select=\"fw-form-heading\"></ng-content>\n</label>\n<div class=\"input-wrapper\">\n <ng-content\n select=\"fw-button-toggle, fw-date-input, fw-text-input, fw-number-input, fw-phone-input, fw-textarea-input, fw-select, fw-multi-select, fw-checkbox\"></ng-content>\n</div>\n<p class=\"vision-p4 helper-text\" *ngIf=\"!!helperText && !errorText\">{{ helperText }}</p>\n<p class=\"vision-p4 error-text\" *ngIf=\"!!errorText\">{{ errorText }}</p>\n", styles: [".fw-wrapped-input{display:flex;flex-direction:column;flex:1}.fw-wrapped-input .input-wrapper{max-width:100%;display:flex;flex-direction:row;flex:1;gap:16px}.fw-wrapped-input .input-wrapper>*{flex:1}.fw-wrapped-input .helper-text,.fw-wrapped-input .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0;text-align:left}.fw-wrapped-input .error-text{color:var(--red-base)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FwFormHeadingComponent, selector: "fw-form-heading", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None }); }
8713
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FwWrappedInputComponent, selector: "fw-wrapped-input", inputs: { title: "title", description: "description", helperText: "helperText", errorText: "errorText" }, host: { properties: { "class.fw-wrapped-input": "this.class" } }, ngImport: i0, template: "<label>\n <fw-form-heading *ngIf=\"title\" [title]=\"title\" [description]=\"description\"></fw-form-heading>\n <ng-content select=\"fw-form-heading\"></ng-content>\n</label>\n<div class=\"input-wrapper\">\n <ng-content\n select=\"fw-button-toggle, fw-date-input, fw-text-input, fw-number-input, fw-phone-input, fw-textarea-input, fw-select, fw-multi-select, fw-checkbox, fw-typeahead\"></ng-content>\n</div>\n<p class=\"vision-p4 helper-text\" *ngIf=\"!!helperText && !errorText\">{{ helperText }}</p>\n<p class=\"vision-p4 error-text\" *ngIf=\"!!errorText\">{{ errorText }}</p>\n", styles: [".fw-wrapped-input{display:flex;flex-direction:column;flex:1}.fw-wrapped-input .input-wrapper{max-width:100%;display:flex;flex-direction:row;flex:1;gap:16px}.fw-wrapped-input .input-wrapper>*{flex:1}.fw-wrapped-input .helper-text,.fw-wrapped-input .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0;text-align:left}.fw-wrapped-input .error-text{color:var(--red-base)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FwFormHeadingComponent, selector: "fw-form-heading", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None }); }
8435
8714
  }
8436
8715
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FwWrappedInputComponent, decorators: [{
8437
8716
  type: Component,
8438
- args: [{ selector: 'fw-wrapped-input', encapsulation: ViewEncapsulation.None, template: "<label>\n <fw-form-heading *ngIf=\"title\" [title]=\"title\" [description]=\"description\"></fw-form-heading>\n <ng-content select=\"fw-form-heading\"></ng-content>\n</label>\n<div class=\"input-wrapper\">\n <ng-content\n select=\"fw-button-toggle, fw-date-input, fw-text-input, fw-number-input, fw-phone-input, fw-textarea-input, fw-select, fw-multi-select, fw-checkbox\"></ng-content>\n</div>\n<p class=\"vision-p4 helper-text\" *ngIf=\"!!helperText && !errorText\">{{ helperText }}</p>\n<p class=\"vision-p4 error-text\" *ngIf=\"!!errorText\">{{ errorText }}</p>\n", styles: [".fw-wrapped-input{display:flex;flex-direction:column;flex:1}.fw-wrapped-input .input-wrapper{max-width:100%;display:flex;flex-direction:row;flex:1;gap:16px}.fw-wrapped-input .input-wrapper>*{flex:1}.fw-wrapped-input .helper-text,.fw-wrapped-input .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0;text-align:left}.fw-wrapped-input .error-text{color:var(--red-base)}\n"] }]
8717
+ args: [{ selector: 'fw-wrapped-input', encapsulation: ViewEncapsulation.None, template: "<label>\n <fw-form-heading *ngIf=\"title\" [title]=\"title\" [description]=\"description\"></fw-form-heading>\n <ng-content select=\"fw-form-heading\"></ng-content>\n</label>\n<div class=\"input-wrapper\">\n <ng-content\n select=\"fw-button-toggle, fw-date-input, fw-text-input, fw-number-input, fw-phone-input, fw-textarea-input, fw-select, fw-multi-select, fw-checkbox, fw-typeahead\"></ng-content>\n</div>\n<p class=\"vision-p4 helper-text\" *ngIf=\"!!helperText && !errorText\">{{ helperText }}</p>\n<p class=\"vision-p4 error-text\" *ngIf=\"!!errorText\">{{ errorText }}</p>\n", styles: [".fw-wrapped-input{display:flex;flex-direction:column;flex:1}.fw-wrapped-input .input-wrapper{max-width:100%;display:flex;flex-direction:row;flex:1;gap:16px}.fw-wrapped-input .input-wrapper>*{flex:1}.fw-wrapped-input .helper-text,.fw-wrapped-input .error-text{margin-top:4px;color:var(--typography-light);line-height:13px;margin-left:6px;margin-bottom:0;text-align:left}.fw-wrapped-input .error-text{color:var(--red-base)}\n"] }]
8439
8718
  }], propDecorators: { title: [{
8440
8719
  type: Input
8441
8720
  }], description: [{
@@ -8476,5 +8755,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
8476
8755
  * Generated bundle index. Do not edit.
8477
8756
  */
8478
8757
 
8479
- export { DialogWidth, FwAlertComponent, FwAlertModule, FwAppIconComponent, FwAppIconModule, FwAvatarComponent, FwAvatarModule, FwBackButtonComponent, FwBadgeComponent, FwBadgeModule, FwBreadcrumbsComponent, FwBreadcrumbsModule, FwButtonComponent, FwButtonDangerDirective, FwButtonDirective, FwButtonGroupComponent, FwButtonGroupModule, FwButtonModule, FwButtonPrimaryDirective, FwButtonSecondaryDirective, FwButtonSuccessDirective, FwButtonToggleComponent, FwButtonToggleItemComponent, FwButtonToggleModule, FwCardAttributeComponent, FwCardAuthorComponent, FwCardComponent, FwCardContentComponent, FwCardFooterComponent, FwCardHeaderComponent, FwCardModule, FwCell, FwCellDef, FwCheckboxComponent, FwCheckboxModule, FwChipComponent, FwChipModule, FwColumnDef, FwContainedInputComponent, FwContainedInputModule, FwCrumbComponent, FwDateInputComponent, FwDateInputModule, FwDialogActionsComponent, FwDialogComponent, FwDialogConfirmComponent, FwDialogContentComponent, FwDialogHeaderComponent, FwDialogService, FwDialogSimpleComponent, FwDialogsModule, FwFooterCell, FwFooterCellDef, FwFooterRow, FwFooterRowDef, FwFormHeadingComponent, FwFormHeadingModule, FwGridComponent, FwGridItemComponent, FwHeaderCell, FwHeaderCellDef, FwHeaderRow, FwHeaderRowDef, FwIconButtonComponent, FwIconButtonModule, FwIconComponent, FwIconModule, FwLayoutContextComponent, FwLayoutGroupComponent, FwLayoutPanelComponent, FwLayoutSidebarComponent, FwLayoutToolbarComponent, FwLayoutsModule, FwMenuCloseTriggersDirective, FwMenuComponent, FwMenuContainerComponent, FwMenuHeaderComponent, FwMenuItemComponent, FwMenuItemGroupComponent, FwMenuModule, FwMenuSeparatorComponent, FwMenuSubItemComponent, FwMultiSelectMenuComponent, FwNavbarComponent, FwNavbarHeaderComponent, FwNavbarItemComponent, FwNavbarModule, FwNavbarSubItemComponent, FwNoDataRow, FwNumberInputComponent, FwNumberInputModule, FwPaginatorAdvancedComponent, FwPaginatorComponent, FwPaginatorModule, FwPhoneInputComponent, FwPhoneInputModule, FwPopoverComponent, FwPopoverModule, FwPopoverPanelComponent, FwProgressBarComponent, FwProgressModule, FwProgressSpinnerComponent, FwRadioComponent, FwRadioGroupComponent, FwRadioModule, FwRow, FwRowDef, FwSectionHeadingComponent, FwSectionHeadingModule, FwSelectMenuComponent, FwSelectMenuModule, FwSnackbarComponent, FwSnackbarContainerComponent, FwSnackbarModule, FwSnackbarService, FwStepComponent, FwStepDecoratorComponent, FwStepperComponent, FwStepperModule, FwSubsectionHeadingComponent, FwSwitchComponent, FwSwitchModule, FwTabComponent, FwTabPanelComponent, FwTableComponent, FwTableDenseComponent, FwTableModule, FwTabsComponent, FwTabsModule, FwTextAreaInputComponent, FwTextAreaInputModule, FwTextInputComponent, FwTextInputModule, FwTooltipComponent, FwTooltipModule, FwTooltipPanelComponent, FwValidators, FwWrappedInputComponent, FwWrappedInputModule, LayoutWidth, MenuManagerService, MenuRegisterDirective, MinimalTranslationService, TranslationService, allIcons, genMessageId, notBeforeDate, notFutureDate };
8758
+ export { DialogWidth, FwAlertComponent, FwAlertModule, FwAppIconComponent, FwAppIconModule, FwAvatarComponent, FwAvatarModule, FwBackButtonComponent, FwBadgeComponent, FwBadgeModule, FwBreadcrumbsComponent, FwBreadcrumbsModule, FwButtonComponent, FwButtonDangerDirective, FwButtonDirective, FwButtonGroupComponent, FwButtonGroupModule, FwButtonModule, FwButtonPrimaryDirective, FwButtonSecondaryDirective, FwButtonSuccessDirective, FwButtonToggleComponent, FwButtonToggleItemComponent, FwButtonToggleModule, FwCardAttributeComponent, FwCardAuthorComponent, FwCardComponent, FwCardContentComponent, FwCardFooterComponent, FwCardHeaderComponent, FwCardModule, FwCell, FwCellDef, FwCheckboxComponent, FwCheckboxModule, FwChipComponent, FwChipModule, FwColumnDef, FwContainedInputComponent, FwContainedInputModule, FwCrumbComponent, FwDateInputComponent, FwDateInputModule, FwDialogActionsComponent, FwDialogComponent, FwDialogConfirmComponent, FwDialogContentComponent, FwDialogHeaderComponent, FwDialogService, FwDialogSimpleComponent, FwDialogsModule, FwFooterCell, FwFooterCellDef, FwFooterRow, FwFooterRowDef, FwFormHeadingComponent, FwFormHeadingModule, FwGridComponent, FwGridItemComponent, FwHeaderCell, FwHeaderCellDef, FwHeaderRow, FwHeaderRowDef, FwIconButtonComponent, FwIconButtonModule, FwIconComponent, FwIconModule, FwLayoutContextComponent, FwLayoutGroupComponent, FwLayoutPanelComponent, FwLayoutSidebarComponent, FwLayoutToolbarComponent, FwLayoutsModule, FwMenuCloseTriggersDirective, FwMenuComponent, FwMenuContainerComponent, FwMenuHeaderComponent, FwMenuItemComponent, FwMenuItemGroupComponent, FwMenuModule, FwMenuSeparatorComponent, FwMenuSubItemComponent, FwMultiSelectMenuComponent, FwNavbarComponent, FwNavbarHeaderComponent, FwNavbarItemComponent, FwNavbarModule, FwNavbarSubItemComponent, FwNoDataRow, FwNumberInputComponent, FwNumberInputModule, FwPaginatorAdvancedComponent, FwPaginatorComponent, FwPaginatorModule, FwPhoneInputComponent, FwPhoneInputModule, FwPopoverComponent, FwPopoverModule, FwPopoverPanelComponent, FwProgressBarComponent, FwProgressModule, FwProgressSpinnerComponent, FwRadioComponent, FwRadioGroupComponent, FwRadioModule, FwRow, FwRowDef, FwSectionHeadingComponent, FwSectionHeadingModule, FwSelectMenuComponent, FwSelectMenuModule, FwSnackbarComponent, FwSnackbarContainerComponent, FwSnackbarModule, FwSnackbarService, FwStepComponent, FwStepDecoratorComponent, FwStepperComponent, FwStepperModule, FwSubsectionHeadingComponent, FwSwitchComponent, FwSwitchModule, FwTabComponent, FwTabPanelComponent, FwTableComponent, FwTableDenseComponent, FwTableModule, FwTabsComponent, FwTabsModule, FwTextAreaInputComponent, FwTextAreaInputModule, FwTextInputComponent, FwTextInputModule, FwTooltipComponent, FwTooltipModule, FwTooltipPanelComponent, FwTypeaheadComponent, FwValidators, FwWrappedInputComponent, FwWrappedInputModule, LayoutWidth, MenuManagerService, MenuRegisterDirective, MinimalTranslationService, TranslationService, allIcons, genMessageId, notBeforeDate, notFutureDate };
8480
8759
  //# sourceMappingURL=flywheel-io-vision.mjs.map