@kirbydesign/extensions-angular 4.4.0 → 4.4.1

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.
@@ -22,7 +22,7 @@ var OpenState;
22
22
  })(OpenState || (OpenState = {}));
23
23
 
24
24
  class ComboboxComponent {
25
- static { this.OPEN_DELAY_IN_MS = 100; }
25
+ static { this.HEIGHT_OF_STANDARD_ITEM = 44; }
26
26
  compareAlphabetically(textA, textB) {
27
27
  if (textA < textB) {
28
28
  return -1;
@@ -46,7 +46,7 @@ class ComboboxComponent {
46
46
  return '';
47
47
  }
48
48
  get dropdownMaxHeight() {
49
- return 8 * this.itemHeight;
49
+ return 8 * ComboboxComponent.HEIGHT_OF_STANDARD_ITEM;
50
50
  }
51
51
  get dropdownMinHeight() {
52
52
  return this.itemHeight;
@@ -92,6 +92,7 @@ class ComboboxComponent {
92
92
  // only set the focused item of the search result, if the input has value
93
93
  if (this.textInput?.nativeElement?.value) {
94
94
  this.focusedItem = this._searchItems[0];
95
+ this._virtualScrollViewport?.scrollToIndex(0);
95
96
  }
96
97
  }
97
98
  get items() {
@@ -119,6 +120,7 @@ class ComboboxComponent {
119
120
  this.focusedItem = this._selectedItem;
120
121
  // Keep ControlValueAccessor value in sync with the selected data item
121
122
  this.value = this._selectedItem;
123
+ this.setInputDisplayValue(this.getItemText(this.selectedItem));
122
124
  }
123
125
  }
124
126
  get focusedItem() {
@@ -357,7 +359,7 @@ class ComboboxComponent {
357
359
  }
358
360
  if (!this.isOpen) {
359
361
  this.state = OpenState.opening;
360
- setTimeout(() => this.showPopOver(), ComboboxComponent.OPEN_DELAY_IN_MS);
362
+ this.showPopOver();
361
363
  this.focusedItem = this.selectedItem;
362
364
  }
363
365
  }
@@ -365,8 +367,11 @@ class ComboboxComponent {
365
367
  if (this.state === OpenState.opening) {
366
368
  this.state = OpenState.open;
367
369
  this.popover?.show();
368
- this.scrollToIndexIntoViewWhenOpeningPopup();
369
370
  this.cdr.markForCheck();
371
+ // PopoverComponent.show() appends the element to document.body synchronously but
372
+ // finishes positioning in a requestAnimationFrame. One rAF is enough to let the
373
+ // browser compute layout so the CDK viewport has a real size before we scroll.
374
+ requestAnimationFrame(() => this.scrollToIndexIntoViewWhenOpeningPopup());
370
375
  }
371
376
  }
372
377
  close() {
@@ -654,34 +659,30 @@ class ComboboxComponent {
654
659
  setInputDisplayValue(value) {
655
660
  // We intentionally update the DOM input imperatively ("hard way")
656
661
  // to ensure the visible value is cleared/updated immediately.
657
- if (this.textInput?.nativeElement) {
658
- this.renderer.setProperty(this.textInput.nativeElement, 'value', value);
662
+ if (this.interactiveElement) {
663
+ this.renderer.setProperty(this.interactiveElement, 'value', value);
659
664
  }
660
665
  }
661
666
  scrollFocusedItemIntoViewWhileNavigating() {
662
- const kirbyItems = this.getKirbyItems();
663
- if (!kirbyItems || kirbyItems.length === 0)
664
- return;
665
- if (!this.focusedItem) {
667
+ if (!this.focusedItem || !this._virtualScrollViewport) {
666
668
  return;
667
669
  }
668
- const id = this.getItemId(this.focusedItem);
669
- if (!id)
670
- return;
671
- const match = kirbyItems.toArray().find((el) => {
672
- if (el.nativeElement.id === undefined) {
673
- console.error('Each item must have an id attribute for scroll to work. Ensure that the ´[attr.id]´ is set correctly, and that each item has a unique id value.');
674
- }
675
- return el.nativeElement.id === id;
676
- });
677
- if (!match) {
678
- this.scrollToIndexIntoViewWhenOpeningPopup();
670
+ const focusedIndex = this.searchItems.indexOf(this.focusedItem);
671
+ if (focusedIndex === -1)
679
672
  return;
673
+ const itemTop = focusedIndex * this.itemHeight;
674
+ const itemBottom = itemTop + this.itemHeight;
675
+ const scrollOffset = this._virtualScrollViewport.measureScrollOffset();
676
+ const viewportSize = this._virtualScrollViewport.getViewportSize();
677
+ if (itemTop < scrollOffset) {
678
+ // Item is above the visible area — scroll up so item appears at the top.
679
+ this._virtualScrollViewport.scrollToOffset(itemTop);
680
680
  }
681
- const scrollIntoView = match.nativeElement.scrollIntoView;
682
- if (typeof scrollIntoView === 'function') {
683
- scrollIntoView.call(match.nativeElement, { block: 'nearest' });
681
+ else if (itemBottom > scrollOffset + viewportSize) {
682
+ // Item is below the visible area — scroll down so item appears at the bottom.
683
+ this._virtualScrollViewport.scrollToOffset(itemBottom - viewportSize);
684
684
  }
685
+ this._virtualScrollViewport.checkViewportSize();
685
686
  }
686
687
  getKirbyItems() {
687
688
  return this.kirbyItemsSlotted && this.kirbyItemsSlotted.length
@@ -690,14 +691,9 @@ class ComboboxComponent {
690
691
  }
691
692
  scrollToIndexIntoViewWhenOpeningPopup() {
692
693
  const focusedIndex = this.searchItems.indexOf(this.focusedItem);
693
- if (focusedIndex < 0)
694
- return;
695
- if (focusedIndex === 0) {
696
- this.virtualScrollViewport?.setRenderedRange({ start: 0, end: 20 });
697
- this.virtualScrollViewport?.checkViewportSize();
698
- return;
699
- }
700
- this.virtualScrollViewport?.scrollToIndex(focusedIndex);
694
+ this._virtualScrollViewport?.setRenderedRange({ start: 0, end: 20 });
695
+ this._virtualScrollViewport?.checkViewportSize();
696
+ this._virtualScrollViewport?.scrollToIndex(focusedIndex);
701
697
  }
702
698
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ComboboxComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.ResizeObserverService }], target: i0.ɵɵFactoryTarget.Component }); }
703
699
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: ComboboxComponent, isStandalone: true, selector: "kirby-x-combobox", inputs: { noSearchResultsText: "noSearchResultsText", selectionClearedAnnouncement: "selectionClearedAnnouncement", itemTextProperty: "itemTextProperty", itemHeight: "itemHeight", itemIdProperty: "itemIdProperty", searchFunction: "searchFunction", items: "items", selectedItem: "selectedItem", placeholder: "placeholder", popout: "popout", expand: "expand", disabled: "disabled", hasError: "hasError", size: "size" }, outputs: { hasErrorChange: "hasErrorChange", change: "change" }, host: { listeners: { "mousedown": "onMouseDown($event)", "touchstart": "onTouchStart($event)", "focusout": "onFocusOut()", "keydown.tab": "onTab()", "keydown.escape": "onEscape()", "keydown.enter": "onEnterO($event)", "keydown.arrowUp": "onArrowKeys($event)", "keydown.arrowDown": "onArrowKeys($event)", "keydown.pageUp": "onArrowKeys($event)", "keydown.pageDown": "onArrowKeys($event)", "keydown.home": "onArrowKeys($event)", "keydown.end": "onArrowKeys($event)" }, properties: { "attr.disabled": "this._isDisabled", "attr.no-blur": "this._noBlurOnScroll", "class.expand": "this._isBlockLevel", "class.is-opening": "this._isOpening", "class.is-open": "this.isOpen", "class.has-value": "this.hasValue" } }, providers: [
@@ -710,7 +706,7 @@ class ComboboxComponent {
710
706
  provide: FORM_FIELD_CONTROL,
711
707
  useExisting: forwardRef(() => ComboboxComponent),
712
708
  },
713
- ], queries: [{ propertyName: "itemTemplate", first: true, predicate: ListItemTemplateDirective, descendants: true, read: TemplateRef }, { propertyName: "slottedItems", predicate: ListItemTemplateDirective, read: ElementRef }, { propertyName: "kirbyItemsSlotted", predicate: ItemComponent, read: ElementRef }], viewQueries: [{ propertyName: "cardElement", first: true, predicate: CardComponent, descendants: true, read: ElementRef }, { propertyName: "popover", first: true, predicate: PopoverComponent, descendants: true }, { propertyName: "rootElement", first: true, predicate: ["rootElement"], descendants: true, read: ElementRef, static: true }, { propertyName: "textInput", first: true, predicate: InputComponent, descendants: true, read: ElementRef, static: true }, { propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "kirbyItemsDefault", predicate: ItemComponent, descendants: true, read: ElementRef }], ngImport: i0, template: "<span class=\"kirby-visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ _liveRegionText }}\n</span>\n<div (click)=\"onToggle($event)\" #rootElement>\n <input\n kirby-input\n type=\"text\"\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n [hasError]=\"hasError\"\n [size]=\"size\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.id]=\"_comboboxId\"\n [attr.aria-controls]=\"_listboxId\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-activedescendant]=\"isOpen && focusedItem ? getItemId(focusedItem) : null\"\n (input)=\"onInput($event)\"\n />\n <kirby-icon [name]=\"isOpen ? 'arrow-up' : 'arrow-down'\" kirby-affix=\"suffix\"></kirby-icon>\n</div>\n\n<kirby-popover\n [target]=\"rootElement\"\n [popout]=\"popout\"\n (click)=\"onPopoverClick()\"\n (willHide)=\"onPopoverWillHide()\"\n>\n <kirby-card [attr.id]=\"_listboxId\" [attr.aria-labelledby]=\"_comboboxId\">\n @if (searchItems.length === 0) {\n <kirby-item>\n <p class=\"kirby-item-title no-results\">{{ noSearchResultsText }}</p>\n </kirby-item>\n } @else {\n <cdk-virtual-scroll-viewport\n class=\"combobox-viewport\"\n role=\"listbox\"\n minBufferPx=\"1240\"\n maxBufferPx=\"1620\"\n [itemSize]=\"itemHeight\"\n [style.height.px]=\"viewportHeight\"\n >\n <ng-container *cdkVirtualFor=\"let item of searchItems\">\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || defaultItemTemplate;\n context: {\n $implicit: item,\n selected: item === selectedItem,\n focused: item === focusedItem,\n }\n \"\n ></ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n </kirby-card>\n</kirby-popover>\n\n<ng-template #defaultItemTemplate let-item let-selected=\"selected\" let-focused=\"focused\">\n <kirby-item\n role=\"option\"\n [selectable]=\"true\"\n [selected]=\"selected\"\n [class.focused]=\"focused\"\n [attr.id]=\"getItemId(item)\"\n [attr.aria-selected]=\"selected\"\n (click)=\"onItemSelect(item)\"\n >\n <p class=\"kirby-item-title\">{{ getItemText(item) }}</p>\n @if (selected) {\n <kirby-icon name=\"checkmark-selected\" slot=\"end\"></kirby-icon>\n }\n </kirby-item>\n</ng-template>\n", styles: ["@media(hover:hover)and (pointer:fine){:host{outline:none;border-radius:999px}:host:focus{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}:host:focus:not(:focus-visible){box-shadow:0 0 0 0 transparent}:host:focus-visible{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}}:host{display:inline-block;position:relative;max-width:calc(100vw - 32px)}:host.clicked{box-shadow:none}:host.expand{display:block}:host.expand kirby-card{width:100%;min-width:initial;max-width:initial}:host div>input[kirby-input]{padding-right:40px}:host div>input[kirby-input]:disabled~kirby-icon{color:var(--kirby-semi-dark-shade)}:host div>kirby-icon{display:flex;align-items:center;position:absolute;top:0;bottom:0;right:12px}:host.has-value>div>input[kirby-input]{text-overflow:ellipsis}kirby-popover{--max-height: 352px}kirby-card{display:flex;flex-direction:column;max-height:352px;overflow:hidden;box-shadow:0 0 5px #1c1c1c0a,0 10px 15px -10px #1c1c1c26;max-width:calc(100vw - 32px);min-width:288px}@media(min-width:321px){kirby-card{min-width:343px}}.combobox-viewport{display:block;width:100%}.no-results{color:var(--kirby-text-color-semi-dark)}\n"], dependencies: [{ kind: "component", type: InputComponent, selector: "input[kirby-input]", inputs: ["type", "size", "borderless", "hasError", "autocomplete", "autocorrect", "value", "maxlength", "inputmode"], outputs: ["hasErrorChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PopoverComponent, selector: "kirby-popover", inputs: ["popout", "target"], outputs: ["willHide"] }, { kind: "component", type: CardComponent, selector: "kirby-card", inputs: ["title", "subtitle", "backgroundImageUrl", "hasPadding", "sizes", "variant"] }, { kind: "component", type: ItemComponent, selector: "kirby-item", inputs: ["disabled", "selected", "disclosure", "selectable", "reorderable", "size", "href", "rotateIcon"] }, { kind: "component", type: IconComponent, selector: "kirby-icon", inputs: ["size", "name"] }, { kind: "directive", type: AffixDirective, selector: "[kirby-affix]", inputs: ["kirby-affix"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
709
+ ], queries: [{ propertyName: "itemTemplate", first: true, predicate: ListItemTemplateDirective, descendants: true, read: TemplateRef }, { propertyName: "slottedItems", predicate: ListItemTemplateDirective, read: ElementRef }, { propertyName: "kirbyItemsSlotted", predicate: ItemComponent, read: ElementRef }], viewQueries: [{ propertyName: "cardElement", first: true, predicate: CardComponent, descendants: true, read: ElementRef }, { propertyName: "popover", first: true, predicate: PopoverComponent, descendants: true }, { propertyName: "rootElement", first: true, predicate: ["rootElement"], descendants: true, read: ElementRef, static: true }, { propertyName: "textInput", first: true, predicate: InputComponent, descendants: true, read: ElementRef, static: true }, { propertyName: "_virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "kirbyItemsDefault", predicate: ItemComponent, descendants: true, read: ElementRef }], ngImport: i0, template: "<span class=\"kirby-visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ _liveRegionText }}\n</span>\n<div (click)=\"onToggle($event)\" #rootElement>\n <input\n kirby-input\n type=\"text\"\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n [hasError]=\"hasError\"\n [size]=\"size\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.id]=\"_comboboxId\"\n [attr.aria-controls]=\"_listboxId\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-activedescendant]=\"isOpen && focusedItem ? getItemId(focusedItem) : null\"\n (input)=\"onInput($event)\"\n />\n <kirby-icon [name]=\"isOpen ? 'arrow-up' : 'arrow-down'\" kirby-affix=\"suffix\"></kirby-icon>\n</div>\n\n<kirby-popover\n [target]=\"rootElement\"\n [popout]=\"popout\"\n (click)=\"onPopoverClick()\"\n (willHide)=\"onPopoverWillHide()\"\n>\n <kirby-card [attr.id]=\"_listboxId\" [attr.aria-labelledby]=\"_comboboxId\">\n @if (searchItems.length === 0) {\n <kirby-item>\n <p class=\"kirby-item-title no-results\">{{ noSearchResultsText }}</p>\n </kirby-item>\n } @else {\n <cdk-virtual-scroll-viewport\n class=\"combobox-viewport\"\n role=\"listbox\"\n [itemSize]=\"itemHeight\"\n [style.height.px]=\"viewportHeight\"\n >\n <ng-container *cdkVirtualFor=\"let item of searchItems\">\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || defaultItemTemplate;\n context: {\n $implicit: item,\n selected: item === selectedItem,\n focused: item === focusedItem,\n }\n \"\n ></ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n </kirby-card>\n</kirby-popover>\n\n<ng-template #defaultItemTemplate let-item let-selected=\"selected\" let-focused=\"focused\">\n <kirby-item\n role=\"option\"\n [selectable]=\"true\"\n [selected]=\"selected\"\n [class.focused]=\"focused\"\n [attr.id]=\"getItemId(item)\"\n [attr.aria-selected]=\"selected\"\n (click)=\"onItemSelect(item)\"\n >\n <p class=\"kirby-item-title\">{{ getItemText(item) }}</p>\n @if (selected) {\n <kirby-icon name=\"checkmark-selected\" slot=\"end\"></kirby-icon>\n }\n </kirby-item>\n</ng-template>\n", styles: ["@media(hover:hover)and (pointer:fine){:host{outline:none;border-radius:999px}:host:focus{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}:host:focus:not(:focus-visible){box-shadow:0 0 0 0 transparent}:host:focus-visible{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}}:host{display:inline-block;position:relative;max-width:calc(100vw - 32px)}:host.clicked{box-shadow:none}:host.expand{display:block}:host.expand kirby-card{width:100%;min-width:initial;max-width:initial}:host div>input[kirby-input]{padding-right:40px}:host div>input[kirby-input]:disabled~kirby-icon{color:var(--kirby-semi-dark-shade)}:host div>kirby-icon{display:flex;align-items:center;position:absolute;top:0;bottom:0;right:12px}:host.has-value>div>input[kirby-input]{text-overflow:ellipsis}kirby-popover{--max-height: 352px}kirby-card{display:flex;flex-direction:column;max-height:352px;overflow:hidden;box-shadow:0 0 5px #1c1c1c0a,0 10px 15px -10px #1c1c1c26;max-width:calc(100vw - 32px);min-width:288px}@media(min-width:321px){kirby-card{min-width:343px}}.combobox-viewport{display:block;width:100%}.no-results{color:var(--kirby-text-color-semi-dark)}\n"], dependencies: [{ kind: "component", type: InputComponent, selector: "input[kirby-input]", inputs: ["type", "size", "borderless", "hasError", "autocomplete", "autocorrect", "value", "maxlength", "inputmode"], outputs: ["hasErrorChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PopoverComponent, selector: "kirby-popover", inputs: ["popout", "target"], outputs: ["willHide"] }, { kind: "component", type: CardComponent, selector: "kirby-card", inputs: ["title", "subtitle", "backgroundImageUrl", "hasPadding", "sizes", "variant"] }, { kind: "component", type: ItemComponent, selector: "kirby-item", inputs: ["disabled", "selected", "disclosure", "selectable", "reorderable", "size", "href", "rotateIcon"] }, { kind: "component", type: IconComponent, selector: "kirby-icon", inputs: ["size", "name"] }, { kind: "directive", type: AffixDirective, selector: "[kirby-affix]", inputs: ["kirby-affix"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
714
710
  }
715
711
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ComboboxComponent, decorators: [{
716
712
  type: Component,
@@ -735,7 +731,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
735
731
  CdkFixedSizeVirtualScroll,
736
732
  CdkVirtualScrollViewport,
737
733
  CdkVirtualForOf,
738
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"kirby-visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ _liveRegionText }}\n</span>\n<div (click)=\"onToggle($event)\" #rootElement>\n <input\n kirby-input\n type=\"text\"\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n [hasError]=\"hasError\"\n [size]=\"size\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.id]=\"_comboboxId\"\n [attr.aria-controls]=\"_listboxId\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-activedescendant]=\"isOpen && focusedItem ? getItemId(focusedItem) : null\"\n (input)=\"onInput($event)\"\n />\n <kirby-icon [name]=\"isOpen ? 'arrow-up' : 'arrow-down'\" kirby-affix=\"suffix\"></kirby-icon>\n</div>\n\n<kirby-popover\n [target]=\"rootElement\"\n [popout]=\"popout\"\n (click)=\"onPopoverClick()\"\n (willHide)=\"onPopoverWillHide()\"\n>\n <kirby-card [attr.id]=\"_listboxId\" [attr.aria-labelledby]=\"_comboboxId\">\n @if (searchItems.length === 0) {\n <kirby-item>\n <p class=\"kirby-item-title no-results\">{{ noSearchResultsText }}</p>\n </kirby-item>\n } @else {\n <cdk-virtual-scroll-viewport\n class=\"combobox-viewport\"\n role=\"listbox\"\n minBufferPx=\"1240\"\n maxBufferPx=\"1620\"\n [itemSize]=\"itemHeight\"\n [style.height.px]=\"viewportHeight\"\n >\n <ng-container *cdkVirtualFor=\"let item of searchItems\">\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || defaultItemTemplate;\n context: {\n $implicit: item,\n selected: item === selectedItem,\n focused: item === focusedItem,\n }\n \"\n ></ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n </kirby-card>\n</kirby-popover>\n\n<ng-template #defaultItemTemplate let-item let-selected=\"selected\" let-focused=\"focused\">\n <kirby-item\n role=\"option\"\n [selectable]=\"true\"\n [selected]=\"selected\"\n [class.focused]=\"focused\"\n [attr.id]=\"getItemId(item)\"\n [attr.aria-selected]=\"selected\"\n (click)=\"onItemSelect(item)\"\n >\n <p class=\"kirby-item-title\">{{ getItemText(item) }}</p>\n @if (selected) {\n <kirby-icon name=\"checkmark-selected\" slot=\"end\"></kirby-icon>\n }\n </kirby-item>\n</ng-template>\n", styles: ["@media(hover:hover)and (pointer:fine){:host{outline:none;border-radius:999px}:host:focus{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}:host:focus:not(:focus-visible){box-shadow:0 0 0 0 transparent}:host:focus-visible{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}}:host{display:inline-block;position:relative;max-width:calc(100vw - 32px)}:host.clicked{box-shadow:none}:host.expand{display:block}:host.expand kirby-card{width:100%;min-width:initial;max-width:initial}:host div>input[kirby-input]{padding-right:40px}:host div>input[kirby-input]:disabled~kirby-icon{color:var(--kirby-semi-dark-shade)}:host div>kirby-icon{display:flex;align-items:center;position:absolute;top:0;bottom:0;right:12px}:host.has-value>div>input[kirby-input]{text-overflow:ellipsis}kirby-popover{--max-height: 352px}kirby-card{display:flex;flex-direction:column;max-height:352px;overflow:hidden;box-shadow:0 0 5px #1c1c1c0a,0 10px 15px -10px #1c1c1c26;max-width:calc(100vw - 32px);min-width:288px}@media(min-width:321px){kirby-card{min-width:343px}}.combobox-viewport{display:block;width:100%}.no-results{color:var(--kirby-text-color-semi-dark)}\n"] }]
734
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"kirby-visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ _liveRegionText }}\n</span>\n<div (click)=\"onToggle($event)\" #rootElement>\n <input\n kirby-input\n type=\"text\"\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n [hasError]=\"hasError\"\n [size]=\"size\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.id]=\"_comboboxId\"\n [attr.aria-controls]=\"_listboxId\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-activedescendant]=\"isOpen && focusedItem ? getItemId(focusedItem) : null\"\n (input)=\"onInput($event)\"\n />\n <kirby-icon [name]=\"isOpen ? 'arrow-up' : 'arrow-down'\" kirby-affix=\"suffix\"></kirby-icon>\n</div>\n\n<kirby-popover\n [target]=\"rootElement\"\n [popout]=\"popout\"\n (click)=\"onPopoverClick()\"\n (willHide)=\"onPopoverWillHide()\"\n>\n <kirby-card [attr.id]=\"_listboxId\" [attr.aria-labelledby]=\"_comboboxId\">\n @if (searchItems.length === 0) {\n <kirby-item>\n <p class=\"kirby-item-title no-results\">{{ noSearchResultsText }}</p>\n </kirby-item>\n } @else {\n <cdk-virtual-scroll-viewport\n class=\"combobox-viewport\"\n role=\"listbox\"\n [itemSize]=\"itemHeight\"\n [style.height.px]=\"viewportHeight\"\n >\n <ng-container *cdkVirtualFor=\"let item of searchItems\">\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || defaultItemTemplate;\n context: {\n $implicit: item,\n selected: item === selectedItem,\n focused: item === focusedItem,\n }\n \"\n ></ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n </kirby-card>\n</kirby-popover>\n\n<ng-template #defaultItemTemplate let-item let-selected=\"selected\" let-focused=\"focused\">\n <kirby-item\n role=\"option\"\n [selectable]=\"true\"\n [selected]=\"selected\"\n [class.focused]=\"focused\"\n [attr.id]=\"getItemId(item)\"\n [attr.aria-selected]=\"selected\"\n (click)=\"onItemSelect(item)\"\n >\n <p class=\"kirby-item-title\">{{ getItemText(item) }}</p>\n @if (selected) {\n <kirby-icon name=\"checkmark-selected\" slot=\"end\"></kirby-icon>\n }\n </kirby-item>\n</ng-template>\n", styles: ["@media(hover:hover)and (pointer:fine){:host{outline:none;border-radius:999px}:host:focus{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}:host:focus:not(:focus-visible){box-shadow:0 0 0 0 transparent}:host:focus-visible{transition:all 80ms linear 0ms;box-shadow:0 0 0 2px var(--kirby-background-color),0 0 0 4px #4d90fe}}:host{display:inline-block;position:relative;max-width:calc(100vw - 32px)}:host.clicked{box-shadow:none}:host.expand{display:block}:host.expand kirby-card{width:100%;min-width:initial;max-width:initial}:host div>input[kirby-input]{padding-right:40px}:host div>input[kirby-input]:disabled~kirby-icon{color:var(--kirby-semi-dark-shade)}:host div>kirby-icon{display:flex;align-items:center;position:absolute;top:0;bottom:0;right:12px}:host.has-value>div>input[kirby-input]{text-overflow:ellipsis}kirby-popover{--max-height: 352px}kirby-card{display:flex;flex-direction:column;max-height:352px;overflow:hidden;box-shadow:0 0 5px #1c1c1c0a,0 10px 15px -10px #1c1c1c26;max-width:calc(100vw - 32px);min-width:288px}@media(min-width:321px){kirby-card{min-width:343px}}.combobox-viewport{display:block;width:100%}.no-results{color:var(--kirby-text-color-semi-dark)}\n"] }]
739
735
  }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.ResizeObserverService }], propDecorators: { noSearchResultsText: [{
740
736
  type: Input
741
737
  }], selectionClearedAnnouncement: [{
@@ -804,7 +800,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
804
800
  }], textInput: [{
805
801
  type: ViewChild,
806
802
  args: [InputComponent, { static: true, read: ElementRef }]
807
- }], virtualScrollViewport: [{
803
+ }], _virtualScrollViewport: [{
808
804
  type: ViewChild,
809
805
  args: [CdkVirtualScrollViewport]
810
806
  }], kirbyItemsDefault: [{
@@ -1 +1 @@
1
- {"version":3,"file":"kirbydesign-extensions-angular-combobox.mjs","sources":["../../combobox/src/combobox.types.ts","../../combobox/src/combobox.component.ts","../../combobox/src/combobox.component.html","../../combobox/src/kirbydesign-extensions-angular-combobox.ts"],"sourcesContent":["export enum OpenState {\n closed,\n opening,\n open,\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ContentChild,\n ContentChildren,\n ElementRef,\n EventEmitter,\n forwardRef,\n HostBinding,\n HostListener,\n Input,\n OnDestroy,\n Output,\n QueryList,\n Renderer2,\n RendererStyleFlags2,\n TemplateRef,\n ViewChild,\n ViewChildren,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { CardComponent } from '@kirbydesign/designsystem/card';\nimport { UniqueIdGenerator } from '@kirbydesign/designsystem/helpers';\nimport { ItemComponent } from '@kirbydesign/designsystem/item';\nimport { ListItemTemplateDirective } from '@kirbydesign/designsystem/list';\nimport { HorizontalDirection, PopoverComponent } from '@kirbydesign/designsystem/popover';\nimport { AffixDirective, InputSize } from '@kirbydesign/designsystem/form-field';\nimport {\n EventListenerDisposeFn,\n FORM_FIELD_CONTROL,\n FormFieldControl,\n} from '@kirbydesign/designsystem/types';\nimport { forwardAttributes, ResizeObserverService } from '@kirbydesign/designsystem/shared';\nimport { InputComponent } from '@kirbydesign/designsystem/form-field';\nimport { IconComponent } from '@kirbydesign/designsystem/icon';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n CdkFixedSizeVirtualScroll,\n CdkVirtualForOf,\n CdkVirtualScrollViewport,\n} from '@angular/cdk/scrolling';\nimport { OpenState } from './combobox.types';\n\n@Component({\n selector: 'kirby-x-combobox',\n templateUrl: './combobox.component.html',\n styleUrls: ['./combobox.component.scss'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => ComboboxComponent),\n multi: true,\n },\n {\n provide: FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => ComboboxComponent),\n },\n ],\n imports: [\n InputComponent,\n NgTemplateOutlet,\n PopoverComponent,\n CardComponent,\n ItemComponent,\n IconComponent,\n AffixDirective,\n CdkFixedSizeVirtualScroll,\n CdkVirtualScrollViewport,\n CdkVirtualForOf,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ComboboxComponent\n implements AfterViewInit, OnDestroy, ControlValueAccessor, FormFieldControl\n{\n static readonly OPEN_DELAY_IN_MS = 100;\n private state = OpenState.closed;\n private _popout: HorizontalDirection | `${HorizontalDirection}` = HorizontalDirection.right;\n private _attributesToForward = ['aria-label', 'aria-labelledby'];\n\n public _listboxId: string = UniqueIdGenerator.scopedTo('kirby-x-combobox').next();\n public _comboboxId: string = UniqueIdGenerator.scopedTo('kirby-input').next();\n\n private readonly _defaultSearchFunction = (\n searchTerm: string,\n itemsToSearch: unknown[]\n ): unknown[] => {\n if (!searchTerm) {\n return itemsToSearch;\n }\n\n const lowerSearchTerm = searchTerm.toLowerCase();\n return itemsToSearch\n .filter((item) => this.getItemText(item).toLowerCase().includes(lowerSearchTerm))\n .sort((a, b) => {\n const textA = this.getItemText(a).toLowerCase();\n const textB = this.getItemText(b).toLowerCase();\n\n const textAStartsWith = textA.startsWith(searchTerm);\n const textBStartsWith = textB.startsWith(searchTerm);\n if (textAStartsWith && textBStartsWith) {\n return this.compareAlphabetically(textA, textB);\n }\n\n if (textAStartsWith) {\n return -1;\n }\n\n if (textBStartsWith) {\n return 1;\n }\n\n return this.compareAlphabetically(textA, textB);\n });\n };\n\n private compareAlphabetically(textA: string, textB: string): number {\n if (textA < textB) {\n return -1;\n }\n if (textA > textB) {\n return 1;\n }\n return 0;\n }\n\n /**\n * The text to display when the search returns no results.\n */\n @Input()\n public noSearchResultsText = 'No results found.';\n\n /**\n * The text announced by screen readers when the selection is cleared.\n */\n @Input()\n public selectionClearedAnnouncement = 'Selection cleared.';\n\n public _liveRegionText = '';\n\n /**\n * The name of the property to use as the display text for each item.\n */\n @Input()\n public itemTextProperty: string = 'text';\n protected getItemText(item: unknown): string {\n if (this.isTypeString(item)) {\n return item as string;\n }\n\n if (this.objectHasItemTextProperty(item)) {\n const objectItem = item as Record<string, unknown>;\n const textValue: unknown = objectItem[this.itemTextProperty];\n\n if (typeof textValue === 'string') {\n return textValue;\n }\n }\n return '';\n }\n\n /**\n * The height of each item in the dropdown, in pixels. This is used to calculate the height of the dropdown based on the number of items.\n */\n @Input()\n public itemHeight: number = 44;\n\n protected get dropdownMaxHeight(): number {\n return 8 * this.itemHeight;\n }\n\n protected get dropdownMinHeight(): number {\n return this.itemHeight;\n }\n\n protected get viewportHeight(): number {\n const itemCount = this.searchItems?.length ?? 0;\n\n if (itemCount === 0) {\n return this.dropdownMinHeight;\n }\n\n return Math.min(\n this.dropdownMaxHeight,\n Math.max(this.dropdownMinHeight, itemCount * this.itemHeight)\n );\n }\n\n private isTypeString(item: unknown): boolean {\n return typeof item === 'string';\n }\n\n private objectHasItemTextProperty(item: unknown): boolean {\n return item != undefined && typeof item === 'object' && this.itemTextProperty in item;\n }\n\n private objectHasItemIdProperty(item: unknown): boolean {\n return item != undefined && typeof item === 'object' && this.itemIdProperty in item;\n }\n\n /**\n * The name of the property to use as the unique identifier for each item.\n */\n @Input()\n public itemIdProperty = 'id';\n protected getItemId(item: unknown): string {\n if (this.isTypeString(item)) {\n return item as string;\n }\n\n if (this.objectHasItemIdProperty(item)) {\n const objectItem = item as Record<string, unknown>;\n const idValue: unknown = objectItem[this.itemIdProperty];\n\n if (this.isTypeString(idValue)) {\n return idValue as string;\n }\n }\n\n console.error(\n 'Each item must have an id property for scroll to work. Ensure that the itemIdProperty input is set correctly, and that each item has a unique id value.'\n );\n return '';\n }\n\n /**\n * A function that takes a search term and the list of items, and returns a filtered list of items to display in the dropdown.\n */\n @Input()\n public searchFunction: (searchTerm: string, itemsToSearch: unknown[]) => unknown[] =\n this._defaultSearchFunction;\n\n private _searchItems: unknown[] = [];\n protected get searchItems(): unknown[] {\n return this._searchItems;\n }\n private set searchItems(value: unknown[]) {\n this._searchItems = value;\n if (!this._searchItems) {\n return;\n }\n\n // only set the focused item of the search result, if the input has value\n if (this.textInput?.nativeElement?.value) {\n this.focusedItem = this._searchItems[0];\n }\n }\n\n private _items: unknown[] = [];\n\n get items(): unknown[] {\n return this._items;\n }\n\n /**\n * The list of items to display in the dropdown.\n * @param value\n */\n @Input()\n public set items(value: unknown[]) {\n this._items = value;\n this.searchItems = this._items;\n }\n\n private _selectedItem: unknown = undefined;\n get selectedItem(): unknown {\n return this._selectedItem;\n }\n\n /**\n * The currently selected item.\n * @param value\n */\n @Input()\n public set selectedItem(value: unknown) {\n // Allow clearing by setting undefined\n if (value !== this._selectedItem) {\n this._selectedItem = value;\n this.focusedItem = this._selectedItem;\n // Keep ControlValueAccessor value in sync with the selected data item\n this.value = this._selectedItem;\n }\n }\n\n // _focusedItem keeps track of which element has focus and will be selected\n // if it is activated (by pressing ENTER)\n private _focusedItem: unknown = undefined;\n public get focusedItem(): unknown {\n return this._focusedItem;\n }\n\n public set focusedItem(item: unknown) {\n // the focus might not have changed, but where in the list might\n this.setAriaPosinsetOnElement(item);\n\n if (this._focusedItem === item) {\n return;\n }\n this._focusedItem = item;\n }\n\n private getIndexOfItem(item: unknown): number {\n return this.searchItems.indexOf(item);\n }\n\n private getKirbyElement(item: unknown | undefined): ElementRef<HTMLElement> | undefined {\n const kirbyItems = this.getKirbyItems();\n if (!kirbyItems || !item) {\n return undefined;\n }\n\n const itemId = this.getItemId(item);\n return kirbyItems.find((el) => el.nativeElement.id === itemId);\n }\n\n private setAriaPosinsetOnElement(item: unknown) {\n const element = this.getKirbyElement(item);\n const index = this.getIndexOfItem(item);\n const setsize = this.searchItems.length;\n\n if (!element) {\n return;\n }\n\n this.renderer.setAttribute(element.nativeElement, 'aria-setsize', setsize.toString());\n this.renderer.setAttribute(element.nativeElement, 'aria-posinset', `${index + 1}`);\n }\n\n /**\n * The placeholder text to display in the input when no item is selected and the input is empty.\n */\n @Input()\n public placeholder = 'Please search...';\n\n /**\n * The direction in which the dropdown should open relative to the input.\n * @param direction\n */\n @Input()\n public set popout(direction: HorizontalDirection | `${HorizontalDirection}`) {\n this._popout = direction || HorizontalDirection.right;\n }\n\n public get popout() {\n return this._popout;\n }\n\n /**\n * If the combobox needs to expand to full width of its parent container, then use expand.\n */\n @Input()\n public expand?: 'block';\n\n /**\n * When `true`, the user cannot interact with the combobox.\n */\n @Input()\n public disabled = false;\n\n @HostBinding('attr.disabled')\n public get _isDisabled(): 'disabled' | null {\n return this.disabled ? 'disabled' : null;\n }\n\n /**\n * Will emit the new value when error changes.\n */\n @Output()\n hasErrorChange: EventEmitter<boolean> = new EventEmitter<boolean>();\n private _hasError: boolean = false;\n\n /**\n * When `true`, the combobox will be styled with error styles.\n */\n @Input()\n get hasError(): boolean {\n return this._hasError;\n }\n\n set hasError(value: boolean) {\n if (this._hasError !== value) {\n this._hasError = value;\n this.hasErrorChange.emit(this._hasError);\n }\n }\n\n /**\n * The size of the input element.\n */\n @Input()\n public size: InputSize = InputSize.medium;\n\n // Prevent Ionic blur on scroll\n @HostBinding('attr.no-blur')\n public get _noBlurOnScroll(): boolean {\n return true;\n }\n\n /**\n * Emitted when an item is selected (tap on mobile, click/keypress on web)\n */\n @Output()\n public change: EventEmitter<unknown> = new EventEmitter<unknown>();\n\n public value: unknown = undefined;\n\n @HostBinding('class.expand')\n public get _isBlockLevel() {\n return this.expand === 'block';\n }\n\n @HostBinding('class.is-opening')\n public get _isOpening(): boolean {\n return this.state === OpenState.opening;\n }\n\n @HostBinding('class.is-open')\n public get isOpen(): boolean {\n return this.state === OpenState.open;\n }\n\n @HostBinding('class.has-value')\n public get hasValue(): boolean {\n return this.selectedItem != null;\n }\n\n @ContentChild(ListItemTemplateDirective, { read: TemplateRef })\n public itemTemplate?: TemplateRef<unknown>;\n\n @ContentChildren(ListItemTemplateDirective, { read: ElementRef })\n public slottedItems?: QueryList<ElementRef<HTMLElement>>;\n\n @ViewChild(CardComponent, { read: ElementRef })\n public cardElement?: ElementRef<HTMLElement>;\n\n @ViewChild(PopoverComponent)\n public popover?: PopoverComponent;\n\n @ViewChild('rootElement', { static: true, read: ElementRef })\n public rootElement!: ElementRef<HTMLElement>;\n\n @ViewChild(InputComponent, { static: true, read: ElementRef })\n private textInput!: ElementRef<HTMLInputElement>;\n\n get interactiveElement(): HTMLElement {\n return this.textInput.nativeElement;\n }\n\n @ViewChild(CdkVirtualScrollViewport)\n private virtualScrollViewport?: CdkVirtualScrollViewport;\n\n private forwardAriaLabelToCombobox() {\n forwardAttributes(\n this.elementRef.nativeElement,\n this._attributesToForward,\n this.renderer,\n this.rootElement.nativeElement\n );\n }\n\n @ViewChildren(ItemComponent, { read: ElementRef })\n public kirbyItemsDefault?: QueryList<ElementRef<HTMLElement>>;\n\n _kirbyItemsSlotted?: QueryList<ElementRef<HTMLElement>>;\n @ContentChildren(ItemComponent, { read: ElementRef })\n public set kirbyItemsSlotted(kirbyItems: QueryList<ElementRef<HTMLElement>>) {\n const hasSlottedItems = this.disposeItemClickListeners?.length > 0;\n if (hasSlottedItems) {\n this.unlistenAllSlottedItems();\n }\n\n kirbyItems.forEach((kirbyItem) => {\n this.renderer.setAttribute(kirbyItem.nativeElement, 'role', 'option');\n const disposeClickListener: EventListenerDisposeFn = this.renderer.listen(\n kirbyItem.nativeElement,\n 'click',\n () => {\n const id = kirbyItem.nativeElement.getAttribute('id');\n const item = this.items.find((it) => this.getItemId(it) === id);\n if (item) {\n this.onItemSelect(item);\n }\n }\n );\n\n this.disposeItemClickListeners.push(disposeClickListener);\n });\n\n this._kirbyItemsSlotted = kirbyItems;\n }\n\n public get kirbyItemsSlotted(): QueryList<ElementRef<HTMLElement>> | undefined {\n return this._kirbyItemsSlotted;\n }\n\n private disposeItemClickListeners: EventListenerDisposeFn[] = [];\n\n public constructor(\n private renderer: Renderer2,\n private elementRef: ElementRef<HTMLElement>,\n private cdr: ChangeDetectorRef,\n private resizeObserverService: ResizeObserverService\n ) {}\n\n protected onToggle(event: MouseEvent) {\n event.stopPropagation();\n this.textInput?.nativeElement.focus();\n\n this.toggle();\n }\n\n private toggle(): void {\n if (this.disabled) {\n return;\n }\n this.isOpen ? this.close() : this.open();\n }\n\n public ngAfterViewInit() {\n if (this.expand === 'block') {\n const { width: initialWidth } = this.elementRef.nativeElement.getBoundingClientRect();\n this.setPopoverCardStyle('max-width', 'initial');\n this.setPopoverCardStyle('min-width', 'initial');\n // Ensure initial width is set even if the resize observer callback also fires initially:\n this.setPopoverCardStyle('--kirby-card-width', `${initialWidth}px`);\n\n this.resizeObserverService.observe(this.elementRef, (entry) => {\n const newWidth = entry.contentRect.width;\n if (newWidth > 0) {\n this.setPopoverCardStyle('--kirby-card-width', `${newWidth}px`);\n }\n });\n }\n this.forwardAriaLabelToCombobox();\n }\n\n /* Utility that makes it easier to set styles on card element */\n private setPopoverCardStyle(style: string, value: string) {\n this.renderer.setStyle(\n this.cardElement?.nativeElement,\n style,\n value,\n RendererStyleFlags2.DashCase\n );\n }\n\n public ngOnDestroy(): void {\n this.unlistenAllSlottedItems();\n this.unobserveResize();\n }\n\n public open(): void {\n if (this.disabled) {\n return;\n }\n if (!this.isOpen) {\n this.state = OpenState.opening;\n setTimeout(() => this.showPopOver(), ComboboxComponent.OPEN_DELAY_IN_MS);\n\n this.focusedItem = this.selectedItem;\n }\n }\n\n private showPopOver() {\n if (this.state === OpenState.opening) {\n this.state = OpenState.open;\n this.popover?.show();\n this.scrollToIndexIntoViewWhenOpeningPopup();\n this.cdr.markForCheck();\n }\n }\n\n public close() {\n if (this.disabled) {\n return;\n }\n if (this.isOpen) {\n this.state = OpenState.closed;\n this.setInputDisplayValue(this.getItemText(this.selectedItem));\n this.searchItems = this.items;\n this.popover?.hide();\n }\n }\n\n protected onItemSelect(item: unknown) {\n // Guard: slotted click listeners should map back to a data item, but be safe.\n if (item instanceof HTMLElement) return;\n this.selectItem(item);\n this.close();\n }\n\n private onChange: (value: unknown) => void = () => {\n /* empty */\n };\n private onTouched: () => void = (): void => {\n /* empty */\n };\n\n /**\n * Sets the select's value. Part of the ControlValueAccessor interface\n * required to integrate with Angular's core forms API.\n *\n * @param value New value to be written to the model.\n */\n public writeValue(value: string): void {\n this.selectItemByInput(value);\n\n // When written from outside, reflect selected text in the input\n this.setInputDisplayValue(this.getItemText(this.value));\n\n this.cdr.markForCheck();\n }\n\n /**\n * Saves a callback function to be invoked when the select's value\n * changes from user input. Part of the ControlValueAccessor interface\n * required to integrate with Angular's core forms API.\n *\n * @param fn Callback to be triggered when the value changes.\n */\n registerOnChange(fn: (value: unknown) => void): void {\n this.onChange = fn;\n }\n\n /**\n * Saves a callback function to be invoked when the select is blurred\n * by the user. Part of the ControlValueAccessor interface required\n * to integrate with Angular's core forms API.\n *\n * @param fn Callback to be triggered when the component has been touched.\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /**\n * Disables the select. Part of the ControlValueAccessor interface required\n * to integrate with Angular's core forms API.\n *\n * @param isDisabled Sets whether the component is disabled.\n */\n public setDisabledState?(isDisabled: boolean): void {\n this.disabled = isDisabled;\n this.cdr.markForCheck();\n }\n\n private selectItem(item: unknown): void {\n if (item != this.selectedItem) {\n this.selectedItem = item;\n this.focusedItem = item;\n this.change.emit(this.value);\n this.onChange(this.value);\n this.setInputDisplayValue(this.getItemText(item));\n this.searchItems = this.items;\n }\n }\n\n private selectItemByInput(input: string): void {\n this.selectedItem = this.findItemByInput(input);\n }\n\n protected onInput(event: Event): void {\n if (!this.isOpen) {\n this.open();\n }\n\n const input = event.target as HTMLInputElement;\n\n if (!input.value) {\n this.clearSelection();\n }\n\n this.updateSearchResults(input.value);\n\n // Screen readers (VoiceOver/NVDA) may move real browser focus to a list-item button.\n // When the list re-renders after filtering, that button is removed from the DOM and\n // focus falls to `document.body`. Restore it to the input so the user can keep typing\n // and the focusout handler doesn't mistake the body-focus for a genuine blur-away.\n if (document.activeElement !== this.textInput?.nativeElement) {\n this.textInput?.nativeElement.focus();\n }\n }\n\n private clearSelection(): void {\n this.selectItem(undefined);\n // Reset after a short delay so the same message can be announced again on subsequent clears\n this.announce(this.selectionClearedAnnouncement);\n }\n\n private _announceTimeout: ReturnType<typeof setTimeout> | undefined;\n private announce(message: string): void {\n clearTimeout(this._announceTimeout);\n this._liveRegionText = '';\n this._announceTimeout = setTimeout(() => {\n this._liveRegionText = message;\n this.cdr.markForCheck();\n }, 100);\n }\n\n private updateSearchResults(inputValue: string): void {\n this.searchItems = inputValue ? this.searchFunction(inputValue, this.items) : this.items;\n\n if (inputValue && this.searchItems.length === 0) {\n this.announce(this.noSearchResultsText);\n }\n }\n\n protected onPopoverWillHide() {\n this.state = OpenState.closed;\n this.rootElement.nativeElement.focus();\n this.onTouched();\n }\n\n protected onPopoverClick() {\n this.close();\n }\n\n @HostListener('mousedown', ['$event'])\n public onMouseDown(event: MouseEvent) {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n }\n\n @HostListener('touchstart', ['$event'])\n public onTouchStart(event: TouchEvent) {\n if (this.isOpen) {\n event.stopPropagation();\n }\n }\n\n @HostListener('focusout')\n public onFocusOut() {\n // Defer the check to allow the browser (and screen readers like VoiceOver/NVDA)\n // to settle focus. `relatedTarget` is often `null` with screen readers, so we\n // inspect `document.activeElement` after the microtask queue has flushed.\n setTimeout(() => {\n const activeElement = document.activeElement as HTMLElement | null;\n const isOnTriggerButton =\n activeElement && this.elementRef.nativeElement.contains(activeElement);\n const isInsidePopover = activeElement && activeElement.closest('kirby-popover');\n\n if (isOnTriggerButton || isInsidePopover) {\n // Focus is still within the component — nothing to do.\n return;\n }\n\n // When a screen reader (VoiceOver/NVDA) moves real focus to a list-item button\n // and the user then types a character, CDK virtual scroll re-renders the list and\n // removes the focused button from the DOM. The browser then drops focus to\n // `document.body`. Detect this case: if the popover is still showing and focus is\n // on the body, it means focus was lost due to DOM removal — restore it to the\n // input rather than closing the popover.\n if (this.isOpen && activeElement === document.body) {\n this.textInput?.nativeElement.focus();\n return;\n }\n\n if (this.isOpen) {\n this.close();\n }\n this.onTouched();\n }, 0);\n }\n\n @HostListener('keydown.tab')\n public onTab() {\n if (this.isOpen) {\n this.selectItem(this.focusedItem);\n this.close();\n }\n }\n\n @HostListener('keydown.escape')\n public onEscape() {\n this.close();\n }\n\n @HostListener('keydown.enter', ['$event'])\n public onEnterO(event: Event) {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.isOpen) {\n this.selectItem(this.focusedItem);\n }\n this.toggle();\n }\n\n @HostListener('keydown.arrowUp', ['$event'])\n @HostListener('keydown.arrowDown', ['$event'])\n @HostListener('keydown.pageUp', ['$event'])\n @HostListener('keydown.pageDown', ['$event'])\n @HostListener('keydown.home', ['$event'])\n @HostListener('keydown.end', ['$event'])\n public onArrowKeys(event: Event): void {\n if (this.disabled) return;\n\n const keyEvent = event as KeyboardEvent; // safe in this context\n // Avoid page scroll\n event.preventDefault();\n\n if (!this.isOpen) {\n this.open();\n if (this.selectedItem) {\n this.setFocusOnSelectedItem();\n } else {\n this.setFocusOnFirstOrLastItem(keyEvent);\n }\n } else {\n this.handleFocusNavigation(keyEvent);\n }\n }\n\n private handleFocusNavigation(keyEvent: KeyboardEvent): void {\n switch (keyEvent.key) {\n case 'ArrowDown':\n this.shiftFocusIndex(1);\n break;\n case 'ArrowUp':\n this.shiftFocusIndex(-1);\n break;\n case 'PageDown':\n this.shiftFocusIndex(10);\n break;\n case 'PageUp':\n this.shiftFocusIndex(-10);\n break;\n case 'Home':\n this.setFocusOnFirstItem();\n break;\n case 'End':\n this.setFocusOnLastItem();\n break;\n default:\n break;\n }\n }\n\n private shiftFocusIndex(numberOfItems: number) {\n // Handle up/down navigation when open\n const currentIndex = this.searchItems.indexOf(this.focusedItem);\n let newIndex;\n\n if (numberOfItems > 0) {\n newIndex = Math.min(this.searchItems.length - 1, currentIndex + numberOfItems);\n } else {\n newIndex = Math.max(0, currentIndex + numberOfItems);\n }\n\n if (newIndex !== currentIndex) {\n this.focusedItem = this.searchItems[newIndex];\n }\n this.scrollFocusedItemIntoViewWhileNavigating();\n }\n\n private setFocusOnFirstOrLastItem(keyEvent: KeyboardEvent): void {\n switch (keyEvent.key) {\n case 'ArrowDown':\n case 'PageDown':\n case 'Home':\n this.setFocusOnFirstItem();\n break;\n case 'ArrowUp':\n case 'PageUp':\n case 'End':\n this.setFocusOnLastItem();\n break;\n default:\n break;\n }\n }\n\n private setFocusOnSelectedItem(): void {\n if (this.selectedItem) {\n this.focusedItem = this.selectedItem;\n }\n }\n\n private setFocusOnLastItem(): void {\n if (this.searchItems.length > 0) {\n this.focusedItem = this.searchItems[this.searchItems.length - 1];\n }\n }\n\n private setFocusOnFirstItem(): void {\n if (this.searchItems.length > 0) {\n this.focusedItem = this.searchItems[0];\n }\n }\n\n private unlistenAllSlottedItems(): void {\n let disposeClickListener: EventListenerDisposeFn | undefined;\n while ((disposeClickListener = this.disposeItemClickListeners.pop()) !== undefined) {\n disposeClickListener();\n }\n }\n\n private unobserveResize() {\n this.resizeObserverService.unobserve(this.elementRef);\n }\n\n /**\n * Resolve a model/data item based on current `items` by comparing displayed text.\n * This is used to map an incoming form value or input `selectedItem` to an item\n * from the list.\n */\n private findItemByInput(input: string): unknown {\n if (!this.items || this.items.length === 0) {\n return input;\n }\n\n return this.items.find((it) => this.getItemText(it) === input) ?? input;\n }\n\n private setInputDisplayValue(value: string): void {\n // We intentionally update the DOM input imperatively (\"hard way\")\n // to ensure the visible value is cleared/updated immediately.\n if (this.textInput?.nativeElement) {\n this.renderer.setProperty(this.textInput.nativeElement, 'value', value);\n }\n }\n\n private scrollFocusedItemIntoViewWhileNavigating(): void {\n const kirbyItems = this.getKirbyItems();\n if (!kirbyItems || kirbyItems.length === 0) return;\n\n if (!this.focusedItem) {\n return;\n }\n\n const id = this.getItemId(this.focusedItem);\n if (!id) return;\n\n const match = kirbyItems.toArray().find((el) => {\n if (el.nativeElement.id === undefined) {\n console.error(\n 'Each item must have an id attribute for scroll to work. Ensure that the ´[attr.id]´ is set correctly, and that each item has a unique id value.'\n );\n }\n return el.nativeElement.id === id;\n });\n\n if (!match) {\n this.scrollToIndexIntoViewWhenOpeningPopup();\n return;\n }\n\n const scrollIntoView = match.nativeElement.scrollIntoView;\n if (typeof scrollIntoView === 'function') {\n scrollIntoView.call(match.nativeElement, { block: 'nearest' });\n }\n }\n\n private getKirbyItems(): QueryList<ElementRef<HTMLElement>> | undefined {\n return this.kirbyItemsSlotted && this.kirbyItemsSlotted.length\n ? this.kirbyItemsSlotted\n : this.kirbyItemsDefault;\n }\n\n private scrollToIndexIntoViewWhenOpeningPopup(): void {\n const focusedIndex = this.searchItems.indexOf(this.focusedItem);\n if (focusedIndex < 0) return;\n\n if (focusedIndex === 0) {\n this.virtualScrollViewport?.setRenderedRange({ start: 0, end: 20 });\n this.virtualScrollViewport?.checkViewportSize();\n return;\n }\n\n this.virtualScrollViewport?.scrollToIndex(focusedIndex);\n }\n}\n","<span class=\"kirby-visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ _liveRegionText }}\n</span>\n<div (click)=\"onToggle($event)\" #rootElement>\n <input\n kirby-input\n type=\"text\"\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n [hasError]=\"hasError\"\n [size]=\"size\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.id]=\"_comboboxId\"\n [attr.aria-controls]=\"_listboxId\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-activedescendant]=\"isOpen && focusedItem ? getItemId(focusedItem) : null\"\n (input)=\"onInput($event)\"\n />\n <kirby-icon [name]=\"isOpen ? 'arrow-up' : 'arrow-down'\" kirby-affix=\"suffix\"></kirby-icon>\n</div>\n\n<kirby-popover\n [target]=\"rootElement\"\n [popout]=\"popout\"\n (click)=\"onPopoverClick()\"\n (willHide)=\"onPopoverWillHide()\"\n>\n <kirby-card [attr.id]=\"_listboxId\" [attr.aria-labelledby]=\"_comboboxId\">\n @if (searchItems.length === 0) {\n <kirby-item>\n <p class=\"kirby-item-title no-results\">{{ noSearchResultsText }}</p>\n </kirby-item>\n } @else {\n <cdk-virtual-scroll-viewport\n class=\"combobox-viewport\"\n role=\"listbox\"\n minBufferPx=\"1240\"\n maxBufferPx=\"1620\"\n [itemSize]=\"itemHeight\"\n [style.height.px]=\"viewportHeight\"\n >\n <ng-container *cdkVirtualFor=\"let item of searchItems\">\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || defaultItemTemplate;\n context: {\n $implicit: item,\n selected: item === selectedItem,\n focused: item === focusedItem,\n }\n \"\n ></ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n </kirby-card>\n</kirby-popover>\n\n<ng-template #defaultItemTemplate let-item let-selected=\"selected\" let-focused=\"focused\">\n <kirby-item\n role=\"option\"\n [selectable]=\"true\"\n [selected]=\"selected\"\n [class.focused]=\"focused\"\n [attr.id]=\"getItemId(item)\"\n [attr.aria-selected]=\"selected\"\n (click)=\"onItemSelect(item)\"\n >\n <p class=\"kirby-item-title\">{{ getItemText(item) }}</p>\n @if (selected) {\n <kirby-icon name=\"checkmark-selected\" slot=\"end\"></kirby-icon>\n }\n </kirby-item>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kirbydesign-extensions-angular-combobox.mjs","sources":["../../combobox/src/combobox.types.ts","../../combobox/src/combobox.component.ts","../../combobox/src/combobox.component.html","../../combobox/src/kirbydesign-extensions-angular-combobox.ts"],"sourcesContent":["export enum OpenState {\n closed,\n opening,\n open,\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ContentChild,\n ContentChildren,\n ElementRef,\n EventEmitter,\n forwardRef,\n HostBinding,\n HostListener,\n Input,\n OnDestroy,\n Output,\n QueryList,\n Renderer2,\n RendererStyleFlags2,\n TemplateRef,\n ViewChild,\n ViewChildren,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { CardComponent } from '@kirbydesign/designsystem/card';\nimport { UniqueIdGenerator } from '@kirbydesign/designsystem/helpers';\nimport { ItemComponent } from '@kirbydesign/designsystem/item';\nimport { ListItemTemplateDirective } from '@kirbydesign/designsystem/list';\nimport { HorizontalDirection, PopoverComponent } from '@kirbydesign/designsystem/popover';\nimport { AffixDirective, InputSize } from '@kirbydesign/designsystem/form-field';\nimport {\n EventListenerDisposeFn,\n FORM_FIELD_CONTROL,\n FormFieldControl,\n} from '@kirbydesign/designsystem/types';\nimport { forwardAttributes, ResizeObserverService } from '@kirbydesign/designsystem/shared';\nimport { InputComponent } from '@kirbydesign/designsystem/form-field';\nimport { IconComponent } from '@kirbydesign/designsystem/icon';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n CdkFixedSizeVirtualScroll,\n CdkVirtualForOf,\n CdkVirtualScrollViewport,\n} from '@angular/cdk/scrolling';\nimport { OpenState } from './combobox.types';\n\n@Component({\n selector: 'kirby-x-combobox',\n templateUrl: './combobox.component.html',\n styleUrls: ['./combobox.component.scss'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => ComboboxComponent),\n multi: true,\n },\n {\n provide: FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => ComboboxComponent),\n },\n ],\n imports: [\n InputComponent,\n NgTemplateOutlet,\n PopoverComponent,\n CardComponent,\n ItemComponent,\n IconComponent,\n AffixDirective,\n CdkFixedSizeVirtualScroll,\n CdkVirtualScrollViewport,\n CdkVirtualForOf,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ComboboxComponent\n implements AfterViewInit, OnDestroy, ControlValueAccessor, FormFieldControl\n{\n private static readonly HEIGHT_OF_STANDARD_ITEM = 44;\n private state = OpenState.closed;\n private _popout: HorizontalDirection | `${HorizontalDirection}` = HorizontalDirection.right;\n private _attributesToForward = ['aria-label', 'aria-labelledby'];\n\n public _listboxId: string = UniqueIdGenerator.scopedTo('kirby-x-combobox').next();\n public _comboboxId: string = UniqueIdGenerator.scopedTo('kirby-input').next();\n\n private readonly _defaultSearchFunction = (\n searchTerm: string,\n itemsToSearch: unknown[]\n ): unknown[] => {\n if (!searchTerm) {\n return itemsToSearch;\n }\n\n const lowerSearchTerm = searchTerm.toLowerCase();\n return itemsToSearch\n .filter((item) => this.getItemText(item).toLowerCase().includes(lowerSearchTerm))\n .sort((a, b) => {\n const textA = this.getItemText(a).toLowerCase();\n const textB = this.getItemText(b).toLowerCase();\n\n const textAStartsWith = textA.startsWith(searchTerm);\n const textBStartsWith = textB.startsWith(searchTerm);\n if (textAStartsWith && textBStartsWith) {\n return this.compareAlphabetically(textA, textB);\n }\n\n if (textAStartsWith) {\n return -1;\n }\n\n if (textBStartsWith) {\n return 1;\n }\n\n return this.compareAlphabetically(textA, textB);\n });\n };\n\n private compareAlphabetically(textA: string, textB: string): number {\n if (textA < textB) {\n return -1;\n }\n if (textA > textB) {\n return 1;\n }\n return 0;\n }\n\n /**\n * The text to display when the search returns no results.\n */\n @Input()\n public noSearchResultsText = 'No results found.';\n\n /**\n * The text announced by screen readers when the selection is cleared.\n */\n @Input()\n public selectionClearedAnnouncement = 'Selection cleared.';\n\n public _liveRegionText = '';\n\n /**\n * The name of the property to use as the display text for each item.\n */\n @Input()\n public itemTextProperty: string = 'text';\n protected getItemText(item: unknown): string {\n if (this.isTypeString(item)) {\n return item as string;\n }\n\n if (this.objectHasItemTextProperty(item)) {\n const objectItem = item as Record<string, unknown>;\n const textValue: unknown = objectItem[this.itemTextProperty];\n\n if (typeof textValue === 'string') {\n return textValue;\n }\n }\n return '';\n }\n\n /**\n * The height of each item in the dropdown, in pixels. This is used to calculate the height of the dropdown based on the number of items.\n */\n @Input()\n public itemHeight: number = 44;\n\n protected get dropdownMaxHeight(): number {\n return 8 * ComboboxComponent.HEIGHT_OF_STANDARD_ITEM;\n }\n\n protected get dropdownMinHeight(): number {\n return this.itemHeight;\n }\n\n protected get viewportHeight(): number {\n const itemCount = this.searchItems?.length ?? 0;\n\n if (itemCount === 0) {\n return this.dropdownMinHeight;\n }\n\n return Math.min(\n this.dropdownMaxHeight,\n Math.max(this.dropdownMinHeight, itemCount * this.itemHeight)\n );\n }\n\n private isTypeString(item: unknown): boolean {\n return typeof item === 'string';\n }\n\n private objectHasItemTextProperty(item: unknown): boolean {\n return item != undefined && typeof item === 'object' && this.itemTextProperty in item;\n }\n\n private objectHasItemIdProperty(item: unknown): boolean {\n return item != undefined && typeof item === 'object' && this.itemIdProperty in item;\n }\n\n /**\n * The name of the property to use as the unique identifier for each item.\n */\n @Input()\n public itemIdProperty = 'id';\n protected getItemId(item: unknown): string {\n if (this.isTypeString(item)) {\n return item as string;\n }\n\n if (this.objectHasItemIdProperty(item)) {\n const objectItem = item as Record<string, unknown>;\n const idValue: unknown = objectItem[this.itemIdProperty];\n\n if (this.isTypeString(idValue)) {\n return idValue as string;\n }\n }\n\n console.error(\n 'Each item must have an id property for scroll to work. Ensure that the itemIdProperty input is set correctly, and that each item has a unique id value.'\n );\n return '';\n }\n\n /**\n * A function that takes a search term and the list of items, and returns a filtered list of items to display in the dropdown.\n */\n @Input()\n public searchFunction: (searchTerm: string, itemsToSearch: any[]) => any[] =\n this._defaultSearchFunction;\n\n private _searchItems: unknown[] = [];\n protected get searchItems(): unknown[] {\n return this._searchItems;\n }\n private set searchItems(value: unknown[]) {\n this._searchItems = value;\n if (!this._searchItems) {\n return;\n }\n\n // only set the focused item of the search result, if the input has value\n if (this.textInput?.nativeElement?.value) {\n this.focusedItem = this._searchItems[0];\n this._virtualScrollViewport?.scrollToIndex(0);\n }\n }\n\n private _items: unknown[] = [];\n\n get items(): unknown[] {\n return this._items;\n }\n\n /**\n * The list of items to display in the dropdown.\n * @param value\n */\n @Input()\n public set items(value: unknown[]) {\n this._items = value;\n this.searchItems = this._items;\n }\n\n private _selectedItem: unknown = undefined;\n get selectedItem(): unknown {\n return this._selectedItem;\n }\n\n /**\n * The currently selected item.\n * @param value\n */\n @Input()\n public set selectedItem(value: unknown) {\n // Allow clearing by setting undefined\n if (value !== this._selectedItem) {\n this._selectedItem = value;\n this.focusedItem = this._selectedItem;\n // Keep ControlValueAccessor value in sync with the selected data item\n this.value = this._selectedItem;\n this.setInputDisplayValue(this.getItemText(this.selectedItem));\n }\n }\n\n // _focusedItem keeps track of which element has focus and will be selected\n // if it is activated (by pressing ENTER)\n private _focusedItem: unknown = undefined;\n public get focusedItem(): unknown {\n return this._focusedItem;\n }\n\n public set focusedItem(item: unknown) {\n // the focus might not have changed, but where in the list might\n this.setAriaPosinsetOnElement(item);\n\n if (this._focusedItem === item) {\n return;\n }\n\n this._focusedItem = item;\n }\n\n private getIndexOfItem(item: unknown): number {\n return this.searchItems.indexOf(item);\n }\n\n private getKirbyElement(item: unknown | undefined): ElementRef<HTMLElement> | undefined {\n const kirbyItems = this.getKirbyItems();\n if (!kirbyItems || !item) {\n return undefined;\n }\n\n const itemId = this.getItemId(item);\n return kirbyItems.find((el) => el.nativeElement.id === itemId);\n }\n\n private setAriaPosinsetOnElement(item: unknown) {\n const element = this.getKirbyElement(item);\n const index = this.getIndexOfItem(item);\n const setsize = this.searchItems.length;\n\n if (!element) {\n return;\n }\n\n this.renderer.setAttribute(element.nativeElement, 'aria-setsize', setsize.toString());\n this.renderer.setAttribute(element.nativeElement, 'aria-posinset', `${index + 1}`);\n }\n\n /**\n * The placeholder text to display in the input when no item is selected and the input is empty.\n */\n @Input()\n public placeholder = 'Please search...';\n\n /**\n * The direction in which the dropdown should open relative to the input.\n * @param direction\n */\n @Input()\n public set popout(direction: HorizontalDirection | `${HorizontalDirection}`) {\n this._popout = direction || HorizontalDirection.right;\n }\n\n public get popout() {\n return this._popout;\n }\n\n /**\n * If the combobox needs to expand to full width of its parent container, then use expand.\n */\n @Input()\n public expand?: 'block';\n\n /**\n * When `true`, the user cannot interact with the combobox.\n */\n @Input()\n public disabled = false;\n\n @HostBinding('attr.disabled')\n public get _isDisabled(): 'disabled' | null {\n return this.disabled ? 'disabled' : null;\n }\n\n /**\n * Will emit the new value when error changes.\n */\n @Output()\n hasErrorChange: EventEmitter<boolean> = new EventEmitter<boolean>();\n private _hasError: boolean = false;\n\n /**\n * When `true`, the combobox will be styled with error styles.\n */\n @Input()\n get hasError(): boolean {\n return this._hasError;\n }\n\n set hasError(value: boolean) {\n if (this._hasError !== value) {\n this._hasError = value;\n this.hasErrorChange.emit(this._hasError);\n }\n }\n\n /**\n * The size of the input element.\n */\n @Input()\n public size: InputSize = InputSize.medium;\n\n // Prevent Ionic blur on scroll\n @HostBinding('attr.no-blur')\n public get _noBlurOnScroll(): boolean {\n return true;\n }\n\n /**\n * Emitted when an item is selected (tap on mobile, click/keypress on web)\n */\n @Output()\n public change: EventEmitter<any> = new EventEmitter<any>();\n\n public value: unknown = undefined;\n\n @HostBinding('class.expand')\n public get _isBlockLevel() {\n return this.expand === 'block';\n }\n\n @HostBinding('class.is-opening')\n public get _isOpening(): boolean {\n return this.state === OpenState.opening;\n }\n\n @HostBinding('class.is-open')\n public get isOpen(): boolean {\n return this.state === OpenState.open;\n }\n\n @HostBinding('class.has-value')\n public get hasValue(): boolean {\n return this.selectedItem != null;\n }\n\n @ContentChild(ListItemTemplateDirective, { read: TemplateRef })\n public itemTemplate?: TemplateRef<unknown>;\n\n @ContentChildren(ListItemTemplateDirective, { read: ElementRef })\n public slottedItems?: QueryList<ElementRef<HTMLElement>>;\n\n @ViewChild(CardComponent, { read: ElementRef })\n public cardElement?: ElementRef<HTMLElement>;\n\n @ViewChild(PopoverComponent)\n public popover?: PopoverComponent;\n\n @ViewChild('rootElement', { static: true, read: ElementRef })\n public rootElement!: ElementRef<HTMLElement>;\n\n @ViewChild(InputComponent, { static: true, read: ElementRef })\n private textInput!: ElementRef<HTMLInputElement>;\n\n get interactiveElement(): HTMLElement {\n return this.textInput.nativeElement;\n }\n\n @ViewChild(CdkVirtualScrollViewport)\n public _virtualScrollViewport?: CdkVirtualScrollViewport;\n\n private forwardAriaLabelToCombobox() {\n forwardAttributes(\n this.elementRef.nativeElement,\n this._attributesToForward,\n this.renderer,\n this.rootElement.nativeElement\n );\n }\n\n @ViewChildren(ItemComponent, { read: ElementRef })\n public kirbyItemsDefault?: QueryList<ElementRef<HTMLElement>>;\n\n _kirbyItemsSlotted?: QueryList<ElementRef<HTMLElement>>;\n @ContentChildren(ItemComponent, { read: ElementRef })\n public set kirbyItemsSlotted(kirbyItems: QueryList<ElementRef<HTMLElement>>) {\n const hasSlottedItems = this.disposeItemClickListeners?.length > 0;\n if (hasSlottedItems) {\n this.unlistenAllSlottedItems();\n }\n\n kirbyItems.forEach((kirbyItem) => {\n this.renderer.setAttribute(kirbyItem.nativeElement, 'role', 'option');\n const disposeClickListener: EventListenerDisposeFn = this.renderer.listen(\n kirbyItem.nativeElement,\n 'click',\n () => {\n const id = kirbyItem.nativeElement.getAttribute('id');\n const item = this.items.find((it) => this.getItemId(it) === id);\n if (item) {\n this.onItemSelect(item);\n }\n }\n );\n\n this.disposeItemClickListeners.push(disposeClickListener);\n });\n\n this._kirbyItemsSlotted = kirbyItems;\n }\n\n public get kirbyItemsSlotted(): QueryList<ElementRef<HTMLElement>> | undefined {\n return this._kirbyItemsSlotted;\n }\n\n private disposeItemClickListeners: EventListenerDisposeFn[] = [];\n\n public constructor(\n private renderer: Renderer2,\n private elementRef: ElementRef<HTMLElement>,\n private cdr: ChangeDetectorRef,\n private resizeObserverService: ResizeObserverService\n ) {}\n\n protected onToggle(event: MouseEvent) {\n event.stopPropagation();\n this.textInput?.nativeElement.focus();\n\n this.toggle();\n }\n\n private toggle(): void {\n if (this.disabled) {\n return;\n }\n this.isOpen ? this.close() : this.open();\n }\n\n public ngAfterViewInit() {\n if (this.expand === 'block') {\n const { width: initialWidth } = this.elementRef.nativeElement.getBoundingClientRect();\n this.setPopoverCardStyle('max-width', 'initial');\n this.setPopoverCardStyle('min-width', 'initial');\n // Ensure initial width is set even if the resize observer callback also fires initially:\n this.setPopoverCardStyle('--kirby-card-width', `${initialWidth}px`);\n\n this.resizeObserverService.observe(this.elementRef, (entry) => {\n const newWidth = entry.contentRect.width;\n if (newWidth > 0) {\n this.setPopoverCardStyle('--kirby-card-width', `${newWidth}px`);\n }\n });\n }\n this.forwardAriaLabelToCombobox();\n }\n\n /* Utility that makes it easier to set styles on card element */\n private setPopoverCardStyle(style: string, value: string) {\n this.renderer.setStyle(\n this.cardElement?.nativeElement,\n style,\n value,\n RendererStyleFlags2.DashCase\n );\n }\n\n public ngOnDestroy(): void {\n this.unlistenAllSlottedItems();\n this.unobserveResize();\n }\n\n public open(): void {\n if (this.disabled) {\n return;\n }\n if (!this.isOpen) {\n this.state = OpenState.opening;\n this.showPopOver();\n this.focusedItem = this.selectedItem;\n }\n }\n\n private showPopOver() {\n if (this.state === OpenState.opening) {\n this.state = OpenState.open;\n this.popover?.show();\n this.cdr.markForCheck();\n // PopoverComponent.show() appends the element to document.body synchronously but\n // finishes positioning in a requestAnimationFrame. One rAF is enough to let the\n // browser compute layout so the CDK viewport has a real size before we scroll.\n requestAnimationFrame(() => this.scrollToIndexIntoViewWhenOpeningPopup());\n }\n }\n\n public close() {\n if (this.disabled) {\n return;\n }\n if (this.isOpen) {\n this.state = OpenState.closed;\n this.setInputDisplayValue(this.getItemText(this.selectedItem));\n this.searchItems = this.items;\n this.popover?.hide();\n }\n }\n\n protected onItemSelect(item: unknown) {\n // Guard: slotted click listeners should map back to a data item, but be safe.\n if (item instanceof HTMLElement) return;\n this.selectItem(item);\n this.close();\n }\n\n private onChange: (value: unknown) => void = () => {\n /* empty */\n };\n private onTouched: () => void = (): void => {\n /* empty */\n };\n\n /**\n * Sets the select's value. Part of the ControlValueAccessor interface\n * required to integrate with Angular's core forms API.\n *\n * @param value New value to be written to the model.\n */\n public writeValue(value: string): void {\n this.selectItemByInput(value);\n\n // When written from outside, reflect selected text in the input\n this.setInputDisplayValue(this.getItemText(this.value));\n\n this.cdr.markForCheck();\n }\n\n /**\n * Saves a callback function to be invoked when the select's value\n * changes from user input. Part of the ControlValueAccessor interface\n * required to integrate with Angular's core forms API.\n *\n * @param fn Callback to be triggered when the value changes.\n */\n registerOnChange(fn: (value: unknown) => void): void {\n this.onChange = fn;\n }\n\n /**\n * Saves a callback function to be invoked when the select is blurred\n * by the user. Part of the ControlValueAccessor interface required\n * to integrate with Angular's core forms API.\n *\n * @param fn Callback to be triggered when the component has been touched.\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /**\n * Disables the select. Part of the ControlValueAccessor interface required\n * to integrate with Angular's core forms API.\n *\n * @param isDisabled Sets whether the component is disabled.\n */\n public setDisabledState?(isDisabled: boolean): void {\n this.disabled = isDisabled;\n this.cdr.markForCheck();\n }\n\n private selectItem(item: unknown): void {\n if (item != this.selectedItem) {\n this.selectedItem = item;\n this.focusedItem = item;\n this.change.emit(this.value);\n this.onChange(this.value);\n this.setInputDisplayValue(this.getItemText(item));\n this.searchItems = this.items;\n }\n }\n\n private selectItemByInput(input: string): void {\n this.selectedItem = this.findItemByInput(input);\n }\n\n protected onInput(event: Event): void {\n if (!this.isOpen) {\n this.open();\n }\n\n const input = event.target as HTMLInputElement;\n\n if (!input.value) {\n this.clearSelection();\n }\n\n this.updateSearchResults(input.value);\n\n // Screen readers (VoiceOver/NVDA) may move real browser focus to a list-item button.\n // When the list re-renders after filtering, that button is removed from the DOM and\n // focus falls to `document.body`. Restore it to the input so the user can keep typing\n // and the focusout handler doesn't mistake the body-focus for a genuine blur-away.\n if (document.activeElement !== this.textInput?.nativeElement) {\n this.textInput?.nativeElement.focus();\n }\n }\n\n private clearSelection(): void {\n this.selectItem(undefined);\n // Reset after a short delay so the same message can be announced again on subsequent clears\n this.announce(this.selectionClearedAnnouncement);\n }\n\n private _announceTimeout: ReturnType<typeof setTimeout> | undefined;\n private announce(message: string): void {\n clearTimeout(this._announceTimeout);\n this._liveRegionText = '';\n this._announceTimeout = setTimeout(() => {\n this._liveRegionText = message;\n this.cdr.markForCheck();\n }, 100);\n }\n\n private updateSearchResults(inputValue: string): void {\n this.searchItems = inputValue ? this.searchFunction(inputValue, this.items) : this.items;\n\n if (inputValue && this.searchItems.length === 0) {\n this.announce(this.noSearchResultsText);\n }\n }\n\n protected onPopoverWillHide() {\n this.state = OpenState.closed;\n this.rootElement.nativeElement.focus();\n this.onTouched();\n }\n\n protected onPopoverClick() {\n this.close();\n }\n\n @HostListener('mousedown', ['$event'])\n public onMouseDown(event: MouseEvent) {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n }\n\n @HostListener('touchstart', ['$event'])\n public onTouchStart(event: TouchEvent) {\n if (this.isOpen) {\n event.stopPropagation();\n }\n }\n\n @HostListener('focusout')\n public onFocusOut() {\n // Defer the check to allow the browser (and screen readers like VoiceOver/NVDA)\n // to settle focus. `relatedTarget` is often `null` with screen readers, so we\n // inspect `document.activeElement` after the microtask queue has flushed.\n setTimeout(() => {\n const activeElement = document.activeElement as HTMLElement | null;\n const isOnTriggerButton =\n activeElement && this.elementRef.nativeElement.contains(activeElement);\n const isInsidePopover = activeElement && activeElement.closest('kirby-popover');\n\n if (isOnTriggerButton || isInsidePopover) {\n // Focus is still within the component — nothing to do.\n return;\n }\n\n // When a screen reader (VoiceOver/NVDA) moves real focus to a list-item button\n // and the user then types a character, CDK virtual scroll re-renders the list and\n // removes the focused button from the DOM. The browser then drops focus to\n // `document.body`. Detect this case: if the popover is still showing and focus is\n // on the body, it means focus was lost due to DOM removal — restore it to the\n // input rather than closing the popover.\n if (this.isOpen && activeElement === document.body) {\n this.textInput?.nativeElement.focus();\n return;\n }\n\n if (this.isOpen) {\n this.close();\n }\n this.onTouched();\n }, 0);\n }\n\n @HostListener('keydown.tab')\n public onTab() {\n if (this.isOpen) {\n this.selectItem(this.focusedItem);\n this.close();\n }\n }\n\n @HostListener('keydown.escape')\n public onEscape() {\n this.close();\n }\n\n @HostListener('keydown.enter', ['$event'])\n public onEnterO(event: Event) {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.isOpen) {\n this.selectItem(this.focusedItem);\n }\n this.toggle();\n }\n\n @HostListener('keydown.arrowUp', ['$event'])\n @HostListener('keydown.arrowDown', ['$event'])\n @HostListener('keydown.pageUp', ['$event'])\n @HostListener('keydown.pageDown', ['$event'])\n @HostListener('keydown.home', ['$event'])\n @HostListener('keydown.end', ['$event'])\n public onArrowKeys(event: Event): void {\n if (this.disabled) return;\n\n const keyEvent = event as KeyboardEvent; // safe in this context\n // Avoid page scroll\n event.preventDefault();\n\n if (!this.isOpen) {\n this.open();\n if (this.selectedItem) {\n this.setFocusOnSelectedItem();\n } else {\n this.setFocusOnFirstOrLastItem(keyEvent);\n }\n } else {\n this.handleFocusNavigation(keyEvent);\n }\n }\n\n private handleFocusNavigation(keyEvent: KeyboardEvent): void {\n switch (keyEvent.key) {\n case 'ArrowDown':\n this.shiftFocusIndex(1);\n break;\n case 'ArrowUp':\n this.shiftFocusIndex(-1);\n break;\n case 'PageDown':\n this.shiftFocusIndex(10);\n break;\n case 'PageUp':\n this.shiftFocusIndex(-10);\n break;\n case 'Home':\n this.setFocusOnFirstItem();\n break;\n case 'End':\n this.setFocusOnLastItem();\n break;\n default:\n break;\n }\n }\n\n private shiftFocusIndex(numberOfItems: number) {\n // Handle up/down navigation when open\n const currentIndex = this.searchItems.indexOf(this.focusedItem);\n let newIndex;\n\n if (numberOfItems > 0) {\n newIndex = Math.min(this.searchItems.length - 1, currentIndex + numberOfItems);\n } else {\n newIndex = Math.max(0, currentIndex + numberOfItems);\n }\n\n if (newIndex !== currentIndex) {\n this.focusedItem = this.searchItems[newIndex];\n }\n this.scrollFocusedItemIntoViewWhileNavigating();\n }\n\n private setFocusOnFirstOrLastItem(keyEvent: KeyboardEvent): void {\n switch (keyEvent.key) {\n case 'ArrowDown':\n case 'PageDown':\n case 'Home':\n this.setFocusOnFirstItem();\n break;\n case 'ArrowUp':\n case 'PageUp':\n case 'End':\n this.setFocusOnLastItem();\n break;\n default:\n break;\n }\n }\n\n private setFocusOnSelectedItem(): void {\n if (this.selectedItem) {\n this.focusedItem = this.selectedItem;\n }\n }\n\n private setFocusOnLastItem(): void {\n if (this.searchItems.length > 0) {\n this.focusedItem = this.searchItems[this.searchItems.length - 1];\n }\n }\n\n private setFocusOnFirstItem(): void {\n if (this.searchItems.length > 0) {\n this.focusedItem = this.searchItems[0];\n }\n }\n\n private unlistenAllSlottedItems(): void {\n let disposeClickListener: EventListenerDisposeFn | undefined;\n while ((disposeClickListener = this.disposeItemClickListeners.pop()) !== undefined) {\n disposeClickListener();\n }\n }\n\n private unobserveResize() {\n this.resizeObserverService.unobserve(this.elementRef);\n }\n\n /**\n * Resolve a model/data item based on current `items` by comparing displayed text.\n * This is used to map an incoming form value or input `selectedItem` to an item\n * from the list.\n */\n private findItemByInput(input: string): unknown {\n if (!this.items || this.items.length === 0) {\n return input;\n }\n\n return this.items.find((it) => this.getItemText(it) === input) ?? input;\n }\n\n private setInputDisplayValue(value: string): void {\n // We intentionally update the DOM input imperatively (\"hard way\")\n // to ensure the visible value is cleared/updated immediately.\n if (this.interactiveElement) {\n this.renderer.setProperty(this.interactiveElement, 'value', value);\n }\n }\n\n private scrollFocusedItemIntoViewWhileNavigating(): void {\n if (!this.focusedItem || !this._virtualScrollViewport) {\n return;\n }\n\n const focusedIndex = this.searchItems.indexOf(this.focusedItem);\n if (focusedIndex === -1) return;\n\n const itemTop = focusedIndex * this.itemHeight;\n const itemBottom = itemTop + this.itemHeight;\n const scrollOffset = this._virtualScrollViewport.measureScrollOffset();\n const viewportSize = this._virtualScrollViewport.getViewportSize();\n\n if (itemTop < scrollOffset) {\n // Item is above the visible area — scroll up so item appears at the top.\n this._virtualScrollViewport.scrollToOffset(itemTop);\n } else if (itemBottom > scrollOffset + viewportSize) {\n // Item is below the visible area — scroll down so item appears at the bottom.\n this._virtualScrollViewport.scrollToOffset(itemBottom - viewportSize);\n }\n\n this._virtualScrollViewport.checkViewportSize();\n }\n\n private getKirbyItems(): QueryList<ElementRef<HTMLElement>> | undefined {\n return this.kirbyItemsSlotted && this.kirbyItemsSlotted.length\n ? this.kirbyItemsSlotted\n : this.kirbyItemsDefault;\n }\n\n private scrollToIndexIntoViewWhenOpeningPopup(): void {\n const focusedIndex = this.searchItems.indexOf(this.focusedItem);\n\n this._virtualScrollViewport?.setRenderedRange({ start: 0, end: 20 });\n this._virtualScrollViewport?.checkViewportSize();\n\n this._virtualScrollViewport?.scrollToIndex(focusedIndex);\n }\n}\n","<span class=\"kirby-visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ _liveRegionText }}\n</span>\n<div (click)=\"onToggle($event)\" #rootElement>\n <input\n kirby-input\n type=\"text\"\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n [hasError]=\"hasError\"\n [size]=\"size\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.id]=\"_comboboxId\"\n [attr.aria-controls]=\"_listboxId\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-activedescendant]=\"isOpen && focusedItem ? getItemId(focusedItem) : null\"\n (input)=\"onInput($event)\"\n />\n <kirby-icon [name]=\"isOpen ? 'arrow-up' : 'arrow-down'\" kirby-affix=\"suffix\"></kirby-icon>\n</div>\n\n<kirby-popover\n [target]=\"rootElement\"\n [popout]=\"popout\"\n (click)=\"onPopoverClick()\"\n (willHide)=\"onPopoverWillHide()\"\n>\n <kirby-card [attr.id]=\"_listboxId\" [attr.aria-labelledby]=\"_comboboxId\">\n @if (searchItems.length === 0) {\n <kirby-item>\n <p class=\"kirby-item-title no-results\">{{ noSearchResultsText }}</p>\n </kirby-item>\n } @else {\n <cdk-virtual-scroll-viewport\n class=\"combobox-viewport\"\n role=\"listbox\"\n [itemSize]=\"itemHeight\"\n [style.height.px]=\"viewportHeight\"\n >\n <ng-container *cdkVirtualFor=\"let item of searchItems\">\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate || defaultItemTemplate;\n context: {\n $implicit: item,\n selected: item === selectedItem,\n focused: item === focusedItem,\n }\n \"\n ></ng-container>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n </kirby-card>\n</kirby-popover>\n\n<ng-template #defaultItemTemplate let-item let-selected=\"selected\" let-focused=\"focused\">\n <kirby-item\n role=\"option\"\n [selectable]=\"true\"\n [selected]=\"selected\"\n [class.focused]=\"focused\"\n [attr.id]=\"getItemId(item)\"\n [attr.aria-selected]=\"selected\"\n (click)=\"onItemSelect(item)\"\n >\n <p class=\"kirby-item-title\">{{ getItemText(item) }}</p>\n @if (selected) {\n <kirby-icon name=\"checkmark-selected\" slot=\"end\"></kirby-icon>\n }\n </kirby-item>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kirbydesign/extensions-angular",
3
- "version": "4.4.0",
3
+ "version": "4.4.1",
4
4
  "author": "kirby@bankdata.dk",
5
5
  "repository": {
6
6
  "type": "git",
@@ -5,13 +5,14 @@ import { HorizontalDirection, PopoverComponent } from '@kirbydesign/designsystem
5
5
  import { InputSize } from '@kirbydesign/designsystem/form-field';
6
6
  import { FormFieldControl } from '@kirbydesign/designsystem/types';
7
7
  import { ResizeObserverService } from '@kirbydesign/designsystem/shared';
8
+ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
8
9
 
9
10
  declare class ComboboxComponent implements AfterViewInit, OnDestroy, ControlValueAccessor, FormFieldControl {
10
11
  private renderer;
11
12
  private elementRef;
12
13
  private cdr;
13
14
  private resizeObserverService;
14
- static readonly OPEN_DELAY_IN_MS = 100;
15
+ private static readonly HEIGHT_OF_STANDARD_ITEM;
15
16
  private state;
16
17
  private _popout;
17
18
  private _attributesToForward;
@@ -51,7 +52,7 @@ declare class ComboboxComponent implements AfterViewInit, OnDestroy, ControlValu
51
52
  /**
52
53
  * A function that takes a search term and the list of items, and returns a filtered list of items to display in the dropdown.
53
54
  */
54
- searchFunction: (searchTerm: string, itemsToSearch: unknown[]) => unknown[];
55
+ searchFunction: (searchTerm: string, itemsToSearch: any[]) => any[];
55
56
  private _searchItems;
56
57
  protected get searchItems(): unknown[];
57
58
  private set searchItems(value);
@@ -112,7 +113,7 @@ declare class ComboboxComponent implements AfterViewInit, OnDestroy, ControlValu
112
113
  /**
113
114
  * Emitted when an item is selected (tap on mobile, click/keypress on web)
114
115
  */
115
- change: EventEmitter<unknown>;
116
+ change: EventEmitter<any>;
116
117
  value: unknown;
117
118
  get _isBlockLevel(): boolean;
118
119
  get _isOpening(): boolean;
@@ -125,7 +126,7 @@ declare class ComboboxComponent implements AfterViewInit, OnDestroy, ControlValu
125
126
  rootElement: ElementRef<HTMLElement>;
126
127
  private textInput;
127
128
  get interactiveElement(): HTMLElement;
128
- private virtualScrollViewport?;
129
+ _virtualScrollViewport?: CdkVirtualScrollViewport;
129
130
  private forwardAriaLabelToCombobox;
130
131
  kirbyItemsDefault?: QueryList<ElementRef<HTMLElement>>;
131
132
  _kirbyItemsSlotted?: QueryList<ElementRef<HTMLElement>>;