igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1 lines • 69.3 kB
Source Map (JSON)
{"version":3,"file":"igniteui-angular-select.mjs","sources":["../../../projects/igniteui-angular/select/src/select/select-group.component.ts","../../../projects/igniteui-angular/select/src/select/select-item.component.ts","../../../projects/igniteui-angular/select/src/select/select-item.component.html","../../../projects/igniteui-angular/select/src/select/select-positioning-strategy.ts","../../../projects/igniteui-angular/select/src/select/select-navigation.directive.ts","../../../projects/igniteui-angular/select/src/select/select.component.ts","../../../projects/igniteui-angular/select/src/select/select.component.html","../../../projects/igniteui-angular/select/src/select/public_api.ts","../../../projects/igniteui-angular/select/src/select/select.module.ts","../../../projects/igniteui-angular/select/src/igniteui-angular-select.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { IgxDropDownGroupComponent } from 'igniteui-angular/drop-down';\n\n/**\n * The `<igx-select-item>` is a container intended for row items in\n * a `<igx-select>` container.\n */\n@Component({\n selector: 'igx-select-item-group',\n template: `\n <label id=\"{{labelId}}\">{{ label }}</label>\n <ng-content select=\"igx-select-item\"></ng-content>\n `,\n standalone: true\n})\nexport class IgxSelectGroupComponent extends IgxDropDownGroupComponent {\n}\n","import { Component, Input } from '@angular/core';\nimport { IgxDropDownItemComponent } from 'igniteui-angular/drop-down';\n\n@Component({\n selector: 'igx-select-item',\n\ttemplateUrl: 'select-item.component.html',\n standalone: true\n})\nexport class IgxSelectItemComponent extends IgxDropDownItemComponent {\n /** @hidden @internal */\n public override isHeader: boolean;\n\n private _text: any;\n\n /**\n * Gets/Sets the item's text to be displayed in the select component's input when the item is selected.\n *\n * ```typescript\n * //get\n * let mySelectedItem = this.dropDown.selectedItem;\n * let selectedItemText = mySelectedItem.text;\n * ```\n *\n * ```html\n * // set\n * <igx-select-item [text]=\"'London'\"></igx-select-item>\n * ```\n */\n @Input()\n public get text(): string {\n return this._text;\n }\n\n public set text(text: string) {\n this._text = text;\n }\n\n /** @hidden @internal */\n public get itemText() {\n if (this._text !== undefined) {\n return this._text;\n }\n // If text @Input is undefined, try extract a meaningful item text out of the item template\n return this.elementRef.nativeElement.textContent.trim();\n }\n\n /**\n * Sets/Gets if the item is the currently selected one in the select\n *\n * ```typescript\n * let mySelectedItem = this.select.selectedItem;\n * let isMyItemSelected = mySelectedItem.selected; // true\n * ```\n */\n public override get selected() {\n return !this.isHeader && !this.disabled && this.selection.is_item_selected(this.dropDown.id, this);\n }\n\n public override set selected(value: any) {\n if (value && !this.isHeader && !this.disabled) {\n this.dropDown.selectItem(this);\n }\n }\n}\n","<span class=\"igx-drop-down__content\">\n <ng-content select=\"igx-prefix, [igxPrefix]\"></ng-content>\n <span class=\"igx-drop-down__inner\"><ng-content></ng-content></span>\n <ng-content select=\"igx-suffix, [igxSuffix]\"></ng-content>\n</span>\n","import { VerticalAlignment, HorizontalAlignment, PositionSettings, ConnectedFit, Point, Size, BaseFitPositionStrategy, Util } from 'igniteui-angular/core';\nimport { IPositionStrategy } from 'igniteui-angular/core';\n\nimport { IgxSelectBase } from './select.common';\nimport { PlatformUtil } from 'igniteui-angular/core';\nimport { Optional } from '@angular/core';\nimport { fadeIn, fadeOut } from 'igniteui-angular/animations';\n\n/** @hidden @internal */\nexport class SelectPositioningStrategy extends BaseFitPositionStrategy implements IPositionStrategy {\n private _selectDefaultSettings = {\n horizontalDirection: HorizontalAlignment.Right,\n verticalDirection: VerticalAlignment.Bottom,\n horizontalStartPoint: HorizontalAlignment.Left,\n verticalStartPoint: VerticalAlignment.Top,\n openAnimation: fadeIn,\n closeAnimation: fadeOut\n };\n\n // Global variables required for cases of !initialCall (page scroll/overlay repositionAll)\n private global_yOffset = 0;\n private global_xOffset = 0;\n private global_styles: SelectStyles = {};\n\n constructor(public select: IgxSelectBase, settings?: PositionSettings, @Optional() protected platform?: PlatformUtil) {\n super();\n this.settings = Object.assign({}, this._selectDefaultSettings, settings);\n }\n\n /**\n * Position the element based on the PositionStrategy implementing this interface.\n *\n * @param contentElement The HTML element to be positioned\n * @param size Size of the element\n * @param document reference to the Document object\n * @param initialCall should be true if this is the initial call to the method\n * @param target attaching target for the component to show\n * ```typescript\n * settings.positionStrategy.position(content, size, document, true);\n * ```\n */\n public override position(contentElement: HTMLElement,\n size: Size,\n document?: Document,\n initialCall?: boolean,\n target?: Point | HTMLElement): void {\n const targetElement = target;\n const rects = super.calculateElementRectangles(contentElement, targetElement);\n // selectFit obj, to be used for both cases of initialCall and !initialCall(page scroll/overlay repositionAll)\n const selectFit: SelectFit = {\n verticalOffset: this.global_yOffset,\n horizontalOffset: this.global_xOffset,\n targetRect: rects.targetRect,\n contentElementRect: rects.elementRect,\n styles: this.global_styles,\n scrollContainer: this.select.scrollContainer,\n scrollContainerRect: this.select.scrollContainer.getBoundingClientRect()\n };\n\n if (initialCall) {\n this.select.scrollContainer.scrollTop = 0;\n // Fill in the required selectFit object properties.\n selectFit.viewPortRect = Util.getViewportRect(document);\n selectFit.itemElement = this.getInteractionItemElement();\n selectFit.itemRect = selectFit.itemElement.getBoundingClientRect();\n\n // Calculate input and selected item elements style related variables\n selectFit.styles = this.calculateStyles(selectFit, targetElement);\n\n selectFit.scrollAmount = this.calculateScrollAmount(selectFit);\n // Calculate how much to offset the overlay container.\n this.calculateYoffset(selectFit);\n this.calculateXoffset(selectFit);\n\n super.updateViewPortFit(selectFit);\n // container does not fit in viewPort and is out on Top or Bottom\n if (selectFit.fitVertical.back < 0 || selectFit.fitVertical.forward < 0) {\n this.fitInViewport(contentElement, selectFit);\n }\n // Calculate scrollTop independently of the dropdown, as we cover all `igsSelect` specific positioning and\n // scrolling to selected item scenarios here.\n this.select.scrollContainer.scrollTop = selectFit.scrollAmount;\n }\n this.setStyles(contentElement, selectFit);\n }\n\n /**\n * Obtain the selected item if there is such one or otherwise use the first one\n */\n public getInteractionItemElement(): HTMLElement {\n let itemElement;\n if (this.select.selectedItem) {\n itemElement = this.select.selectedItem.element.nativeElement;\n } else {\n itemElement = this.select.getFirstItemElement();\n }\n return itemElement;\n }\n\n /**\n * Position the items outer container so selected item text is positioned over input text and if header\n * And/OR footer - both header/footer are visible\n *\n * @param selectFit selectFit to use for computation.\n */\n protected fitInViewport(contentElement: HTMLElement, selectFit: SelectFit) {\n const footer = selectFit.scrollContainerRect.bottom - selectFit.contentElementRect.bottom;\n const header = selectFit.scrollContainerRect.top - selectFit.contentElementRect.top;\n const lastItemFitSize = selectFit.targetRect.bottom + selectFit.styles.itemTextToInputTextDiff - footer;\n const firstItemFitSize = selectFit.targetRect.top - selectFit.styles.itemTextToInputTextDiff - header;\n // out of viewPort on Top\n if (selectFit.fitVertical.back < 0) {\n const possibleScrollAmount = selectFit.scrollContainer.scrollHeight -\n selectFit.scrollContainerRect.height - selectFit.scrollAmount;\n if (possibleScrollAmount + selectFit.fitVertical.back > 0 && firstItemFitSize > selectFit.viewPortRect.top) {\n selectFit.scrollAmount -= selectFit.fitVertical.back;\n selectFit.verticalOffset -= selectFit.fitVertical.back;\n this.global_yOffset = selectFit.verticalOffset;\n } else {\n selectFit.verticalOffset = 0 ;\n this.global_yOffset = 0;\n }\n // out of viewPort on Bottom\n } else if (selectFit.fitVertical.forward < 0) {\n if (selectFit.scrollAmount + selectFit.fitVertical.forward > 0 && lastItemFitSize < selectFit.viewPortRect.bottom) {\n selectFit.scrollAmount += selectFit.fitVertical.forward;\n selectFit.verticalOffset += selectFit.fitVertical.forward;\n this.global_yOffset = selectFit.verticalOffset;\n } else {\n selectFit.verticalOffset = -selectFit.contentElementRect.height + selectFit.targetRect.height;\n this.global_yOffset = selectFit.verticalOffset;\n }\n }\n }\n\n /**\n * Sets element's style which effectively positions the provided element\n *\n * @param element Element to position\n * @param selectFit selectFit to use for computation.\n * @param initialCall should be true if this is the initial call to the position method calling setStyles\n */\n protected setStyles(contentElement: HTMLElement, selectFit: SelectFit) {\n super.setStyle(contentElement, selectFit.targetRect, selectFit.contentElementRect, selectFit);\n contentElement.style.width = `${selectFit.styles.contentElementNewWidth}px`; // manage container based on paddings?\n this.global_styles.contentElementNewWidth = selectFit.styles.contentElementNewWidth;\n }\n\n /**\n * Calculate selected item scroll position.\n */\n private calculateScrollAmount(selectFit: SelectFit): number {\n const itemElementRect = selectFit.itemRect;\n const scrollContainer = selectFit.scrollContainer;\n const scrollContainerRect = selectFit.scrollContainerRect;\n const scrollDelta = scrollContainerRect.top - itemElementRect.top;\n let scrollPosition = scrollContainer.scrollTop - scrollDelta;\n\n const dropDownHeight = scrollContainer.clientHeight;\n scrollPosition -= dropDownHeight / 2;\n scrollPosition += itemElementRect.height / 2;\n\n return Math.round(Math.min(Math.max(0, scrollPosition), scrollContainer.scrollHeight - scrollContainerRect.height));\n }\n\n /**\n * Calculate the necessary input and selected item styles to be used for positioning item text over input text.\n * Calculate & Set default items container width.\n *\n * @param selectFit selectFit to use for computation.\n */\n private calculateStyles(selectFit: SelectFit, target: Point | HTMLElement): SelectStyles {\n const styles: SelectStyles = {};\n const inputElementStyles = window.getComputedStyle(target as Element);\n const itemElementStyles = window.getComputedStyle(selectFit.itemElement);\n const numericInputFontSize = parseFloat(inputElementStyles.fontSize);\n const numericInputPaddingTop = parseFloat(inputElementStyles.paddingTop);\n const numericInputPaddingBottom = parseFloat(inputElementStyles.paddingBottom);\n const numericItemFontSize = parseFloat(itemElementStyles.fontSize);\n const inputTextToInputTop = ((selectFit.targetRect.bottom - numericInputPaddingBottom)\n - (selectFit.targetRect.top + numericInputPaddingTop) - numericInputFontSize) / 2;\n const itemTextToItemTop = (selectFit.itemRect.height - numericItemFontSize) / 2;\n styles.itemTextToInputTextDiff = Math.round(itemTextToItemTop - inputTextToInputTop - numericInputPaddingTop);\n\n const numericLeftPadding = parseFloat(itemElementStyles.paddingLeft);\n const numericTextIndent = parseFloat(itemElementStyles.textIndent);\n\n styles.itemTextPadding = numericLeftPadding;\n styles.itemTextIndent = numericTextIndent;\n // 24 is the input's toggle ddl icon width\n styles.contentElementNewWidth = selectFit.targetRect.width + 24 + numericLeftPadding * 2;\n\n return styles;\n }\n\n /**\n * Calculate how much to offset the overlay container for Y-axis.\n */\n private calculateYoffset(selectFit: SelectFit) {\n selectFit.verticalOffset = -(selectFit.itemRect.top - selectFit.contentElementRect.top +\n selectFit.styles.itemTextToInputTextDiff - selectFit.scrollAmount);\n this.global_yOffset = selectFit.verticalOffset;\n }\n\n /**\n * Calculate how much to offset the overlay container for X-axis.\n */\n private calculateXoffset(selectFit: SelectFit) {\n selectFit.horizontalOffset = selectFit.styles.itemTextIndent - selectFit.styles.itemTextPadding;\n this.global_xOffset = selectFit.horizontalOffset;\n }\n}\n\n/** @hidden */\nexport interface SelectFit extends ConnectedFit {\n itemElement?: HTMLElement;\n scrollContainer: HTMLElement;\n scrollContainerRect: ClientRect;\n itemRect?: ClientRect;\n styles?: SelectStyles;\n scrollAmount?: number;\n}\n\n/** @hidden */\nexport interface SelectStyles {\n itemTextPadding?: number;\n itemTextIndent?: number;\n itemTextToInputTextDiff?: number;\n contentElementNewWidth?: number;\n numericLeftPadding?: number;\n}\n","import { Directive, Input, OnDestroy } from '@angular/core';\nimport { Subscription, timer } from 'rxjs';\nimport { IgxSelectItemComponent } from './select-item.component';\nimport { IgxSelectBase } from './select.common';\nimport { IgxDropDownItemNavigationDirective } from 'igniteui-angular/drop-down';\n\n/** @hidden @internal */\n@Directive({\n selector: '[igxSelectItemNavigation]',\n standalone: true\n})\nexport class IgxSelectItemNavigationDirective extends IgxDropDownItemNavigationDirective implements OnDestroy {\n protected override _target: IgxSelectBase = null;\n\n @Input('igxSelectItemNavigation')\n public override get target(): IgxSelectBase {\n return this._target;\n }\n public override set target(target: IgxSelectBase) {\n this._target = target ? target : this.dropdown as IgxSelectBase;\n }\n\n /** Captures keydown events and calls the appropriate handlers on the target component */\n public override handleKeyDown(event: KeyboardEvent) {\n if (!event) {\n return;\n }\n\n const key = event.key.toLowerCase();\n if (event.altKey && (key === 'arrowdown' || key === 'arrowup' || key === 'down' || key === 'up')) {\n this.target.toggle();\n return;\n }\n\n if (this.target.collapsed) {\n switch (key) {\n case 'space':\n case 'spacebar':\n case ' ':\n case 'enter':\n event.preventDefault();\n this.target.open();\n return;\n case 'arrowdown':\n case 'down':\n this.target.navigateNext();\n this.target.selectItem(this.target.focusedItem);\n event.preventDefault();\n return;\n case 'arrowup':\n case 'up':\n this.target.navigatePrev();\n this.target.selectItem(this.target.focusedItem);\n event.preventDefault();\n return;\n default:\n break;\n }\n } else if (key === 'tab' || event.shiftKey && key === 'tab') {\n this.target.close();\n }\n\n super.handleKeyDown(event);\n this.captureKey(event);\n }\n\n private inputStream = '';\n private clearStream$ = Subscription.EMPTY;\n\n public captureKey(event: KeyboardEvent) {\n // relying only on key, available on all major browsers:\n // https://caniuse.com/#feat=keyboardevent-key (IE/Edge quirk doesn't affect letter typing)\n if (!event || !event.key || event.key.length > 1 || event.key === ' ' || event.key === 'spacebar') {\n // ignore longer keys ('Alt', 'ArrowDown', etc) AND spacebar (used of open/close)\n return;\n }\n\n this.clearStream$.unsubscribe();\n this.clearStream$ = timer(500).subscribe(() => {\n this.inputStream = '';\n });\n\n this.inputStream += event.key;\n const focusedItem = this.target.focusedItem as IgxSelectItemComponent;\n\n // select the item\n if (focusedItem && this.inputStream.length > 1 && focusedItem.itemText.toLowerCase().startsWith(this.inputStream.toLowerCase())) {\n return;\n }\n this.activateItemByText(this.inputStream);\n }\n\n public activateItemByText(text: string) {\n const items = this.target.items as IgxSelectItemComponent[];\n\n // ^ this is focused OR selected if the dd is closed\n\n let nextItem = this.findNextItem(items, text);\n\n // If there is no such an item starting with the current text input stream AND the last Char in the input stream\n // is the same as the first one, find next item starting with the same first Char.\n // Covers cases of holding down the same key Ex: \"pppppp\" that iterates trough list items starting with \"p\".\n if (!nextItem && text.charAt(0) === text.charAt(text.length - 1)) {\n text = text.slice(0, 1);\n nextItem = this.findNextItem(items, text);\n }\n\n // If there is no other item to be found, do not change the active item.\n if (!nextItem) {\n return;\n }\n\n if (this.target.collapsed) {\n this.target.selectItem(nextItem);\n }\n this.target.navigateItem(items.indexOf(nextItem));\n }\n\n public ngOnDestroy(): void {\n this.clearStream$.unsubscribe();\n }\n\n private findNextItem(items: IgxSelectItemComponent[], text: string) {\n const activeItemIndex = items.indexOf(this.target.focusedItem as IgxSelectItemComponent) || 0;\n\n // Match next item in ddl items and wrap around if needed\n return items.slice(activeItemIndex + 1).find(x => !x.disabled && (x.itemText.toLowerCase().startsWith(text.toLowerCase()))) ||\n items.slice(0, activeItemIndex).find(x => !x.disabled && (x.itemText.toLowerCase().startsWith(text.toLowerCase())));\n }\n}\n","import { AfterContentChecked, AfterContentInit, AfterViewInit, booleanAttribute, Component, ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, HostBinding, Injector, Input, OnDestroy, OnInit, Output, QueryList, TemplateRef, ViewChild, ViewChildren, inject } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { AbstractControl, ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { noop } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\nimport {\n EditorProvider,\n IBaseCancelableBrowserEventArgs,\n IBaseEventArgs,\n AbsoluteScrollStrategy,\n OverlaySettings\n} from 'igniteui-angular/core';\nimport { IgxSelectItemComponent } from './select-item.component';\nimport { SelectPositioningStrategy } from './select-positioning-strategy';\nimport { IgxSelectBase } from './select.common';\nimport { IgxHintDirective, IgxInputGroupType, IgxPrefixDirective, IGX_INPUT_GROUP_TYPE, IgxInputGroupComponent, IgxInputDirective, IgxInputState, IgxLabelDirective, IgxReadOnlyInputDirective, IgxSuffixDirective } from 'igniteui-angular/input-group';\nimport { ToggleViewCancelableEventArgs, ToggleViewEventArgs, IgxToggleDirective } from 'igniteui-angular/directives';\nimport { IgxOverlayService } from 'igniteui-angular/core';\nimport { IgxIconComponent } from 'igniteui-angular/icon';\nimport { IgxSelectItemNavigationDirective } from './select-navigation.directive';\nimport { IGX_DROPDOWN_BASE, IgxDropDownComponent, IgxDropDownItemBaseDirective, ISelectionEventArgs, Navigate } from 'igniteui-angular/drop-down';\n\n/** @hidden @internal */\n@Directive({\n selector: '[igxSelectToggleIcon]',\n standalone: true\n})\nexport class IgxSelectToggleIconDirective {\n}\n\n/** @hidden @internal */\n@Directive({\n selector: '[igxSelectHeader]',\n standalone: true\n})\nexport class IgxSelectHeaderDirective {\n}\n\n/** @hidden @internal */\n@Directive({\n selector: '[igxSelectFooter]',\n standalone: true\n})\nexport class IgxSelectFooterDirective {\n}\n\n/**\n * **Ignite UI for Angular Select** -\n * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/select)\n *\n * The `igxSelect` provides an input with dropdown list allowing selection of a single item.\n *\n * Example:\n * ```html\n * <igx-select #select1 [placeholder]=\"'Pick One'\">\n * <label igxLabel>Select Label</label>\n * <igx-select-item *ngFor=\"let item of items\" [value]=\"item.field\">\n * {{ item.field }}\n * </igx-select-item>\n * </igx-select>\n * ```\n */\n@Component({\n selector: 'igx-select',\n templateUrl: './select.component.html',\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: IgxSelectComponent, multi: true },\n { provide: IGX_DROPDOWN_BASE, useExisting: IgxSelectComponent }\n ],\n styles: [`\n :host {\n display: block;\n }\n `],\n imports: [IgxInputGroupComponent, IgxInputDirective, IgxSelectItemNavigationDirective, IgxSuffixDirective, IgxReadOnlyInputDirective, NgTemplateOutlet, IgxIconComponent, IgxToggleDirective]\n})\nexport class IgxSelectComponent extends IgxDropDownComponent implements IgxSelectBase, ControlValueAccessor,\n AfterContentInit, OnInit, AfterViewInit, OnDestroy, EditorProvider, AfterContentChecked {\n protected overlayService = inject<IgxOverlayService>(IgxOverlayService);\n private _inputGroupType = inject<IgxInputGroupType>(IGX_INPUT_GROUP_TYPE, { optional: true });\n private _injector = inject(Injector);\n\n\n /** @hidden @internal */\n @ViewChild('inputGroup', { read: IgxInputGroupComponent, static: true }) public inputGroup: IgxInputGroupComponent;\n\n /** @hidden @internal */\n @ViewChild('input', { read: IgxInputDirective, static: true }) public input: IgxInputDirective;\n\n /** @hidden @internal */\n @ContentChildren(forwardRef(() => IgxSelectItemComponent), { descendants: true })\n public override children: QueryList<IgxSelectItemComponent>;\n\n @ContentChildren(IgxPrefixDirective, { descendants: true })\n protected prefixes: QueryList<IgxPrefixDirective>;\n\n @ContentChildren(IgxSuffixDirective, { descendants: true })\n protected suffixes: QueryList<IgxSuffixDirective>;\n\n @ViewChildren(IgxSuffixDirective)\n protected internalSuffixes: QueryList<IgxSuffixDirective>;\n\n /** @hidden @internal */\n @ContentChild(forwardRef(() => IgxLabelDirective), { static: true }) public label: IgxLabelDirective;\n\n /**\n * Sets input placeholder.\n *\n */\n @Input() public placeholder;\n\n\n /**\n * Disables the component.\n * ```html\n * <igx-select [disabled]=\"'true'\"></igx-select>\n * ```\n */\n @Input({ transform: booleanAttribute }) public disabled = false;\n\n /**\n * Sets custom OverlaySettings `IgxSelectComponent`.\n * ```html\n * <igx-select [overlaySettings] = \"customOverlaySettings\"></igx-select>\n * ```\n */\n @Input()\n public overlaySettings: OverlaySettings;\n\n /** @hidden @internal */\n @HostBinding('style.maxHeight')\n public override maxHeight = '256px';\n\n /**\n * Emitted before the dropdown is opened\n *\n * ```html\n * <igx-select opening='handleOpening($event)'></igx-select>\n * ```\n */\n @Output()\n public override opening = new EventEmitter<IBaseCancelableBrowserEventArgs>();\n\n /**\n * Emitted after the dropdown is opened\n *\n * ```html\n * <igx-select (opened)='handleOpened($event)'></igx-select>\n * ```\n */\n @Output()\n public override opened = new EventEmitter<IBaseEventArgs>();\n\n /**\n * Emitted before the dropdown is closed\n *\n * ```html\n * <igx-select (closing)='handleClosing($event)'></igx-select>\n * ```\n */\n @Output()\n public override closing = new EventEmitter<IBaseCancelableBrowserEventArgs>();\n\n /**\n * Emitted after the dropdown is closed\n *\n * ```html\n * <igx-select (closed)='handleClosed($event)'></igx-select>\n * ```\n */\n @Output()\n public override closed = new EventEmitter<IBaseEventArgs>();\n\n /**\n * The custom template, if any, that should be used when rendering the select TOGGLE(open/close) button\n *\n * ```typescript\n * // Set in typescript\n * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;\n * myComponent.select.toggleIconTemplate = myCustomTemplate;\n * ```\n * ```html\n * <!-- Set in markup -->\n * <igx-select #select>\n * ...\n * <ng-template igxSelectToggleIcon let-collapsed>\n * <igx-icon>{{ collapsed ? 'remove_circle' : 'remove_circle_outline'}}</igx-icon>\n * </ng-template>\n * </igx-select>\n * ```\n */\n @ContentChild(IgxSelectToggleIconDirective, { read: TemplateRef })\n public toggleIconTemplate: TemplateRef<any> = null;\n\n /**\n * The custom template, if any, that should be used when rendering the HEADER for the select items list\n *\n * ```typescript\n * // Set in typescript\n * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;\n * myComponent.select.headerTemplate = myCustomTemplate;\n * ```\n * ```html\n * <!-- Set in markup -->\n * <igx-select #select>\n * ...\n * <ng-template igxSelectHeader>\n * <div class=\"select__header\">\n * This is a custom header\n * </div>\n * </ng-template>\n * </igx-select>\n * ```\n */\n @ContentChild(IgxSelectHeaderDirective, { read: TemplateRef, static: false })\n public headerTemplate: TemplateRef<any> = null;\n\n /**\n * The custom template, if any, that should be used when rendering the FOOTER for the select items list\n *\n * ```typescript\n * // Set in typescript\n * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;\n * myComponent.select.footerTemplate = myCustomTemplate;\n * ```\n * ```html\n * <!-- Set in markup -->\n * <igx-select #select>\n * ...\n * <ng-template igxSelectFooter>\n * <div class=\"select__footer\">\n * This is a custom footer\n * </div>\n * </ng-template>\n * </igx-select>\n * ```\n */\n @ContentChild(IgxSelectFooterDirective, { read: TemplateRef, static: false })\n public footerTemplate: TemplateRef<any> = null;\n\n @ContentChild(IgxHintDirective, { read: ElementRef }) private hintElement: ElementRef;\n\n /** @hidden @internal */\n public override width: string;\n\n /** @hidden @internal do not use the drop-down container class */\n public override cssClass = false;\n\n /** @hidden @internal */\n public override allowItemsFocus = false;\n\n /** @hidden @internal */\n public override height: string;\n\n private ngControl: NgControl = null;\n private _overlayDefaults: OverlaySettings;\n private _value: any;\n private _type = null;\n\n /**\n * Gets/Sets the component value.\n *\n * ```typescript\n * // get\n * let selectValue = this.select.value;\n * ```\n *\n * ```typescript\n * // set\n * this.select.value = 'London';\n * ```\n * ```html\n * <igx-select [value]=\"value\"></igx-select>\n * ```\n */\n @Input()\n public get value(): any {\n return this._value;\n }\n public set value(v: any) {\n if (this._value === v) {\n return;\n }\n this._value = v;\n this.setSelection(this.items.find(x => x.value === this.value));\n }\n\n /**\n * Sets how the select will be styled.\n * The allowed values are `line`, `box` and `border`. The input-group default is `line`.\n * ```html\n * <igx-select [type]=\"'box'\"></igx-select>\n * ```\n */\n @Input()\n public get type(): IgxInputGroupType {\n return this._type || this._inputGroupType || 'line';\n }\n\n public set type(val: IgxInputGroupType) {\n this._type = val;\n }\n\n /** @hidden @internal */\n public get selectionValue() {\n const selectedItem = this.selectedItem;\n return selectedItem ? selectedItem.itemText : '';\n }\n\n /** @hidden @internal */\n public override get selectedItem(): IgxSelectItemComponent {\n return this.selection.first_item(this.id);\n }\n\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n\n //#region ControlValueAccessor\n\n /** @hidden @internal */\n public writeValue = (value: any) => {\n this.value = value;\n };\n\n /** @hidden @internal */\n public registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n /** @hidden @internal */\n public registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n /** @hidden @internal */\n public setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n //#endregion\n\n /** @hidden @internal */\n public getEditElement(): HTMLInputElement {\n return this.input.nativeElement;\n }\n\n /** @hidden @internal */\n public override selectItem(newSelection: IgxDropDownItemBaseDirective, event?) {\n const oldSelection = this.selectedItem ?? <IgxDropDownItemBaseDirective>{};\n\n if (newSelection === null || newSelection.disabled || newSelection.isHeader) {\n return;\n }\n\n if (newSelection === oldSelection) {\n this.toggleDirective.close();\n return;\n }\n\n const args: ISelectionEventArgs = { oldSelection, newSelection, cancel: false, owner: this };\n this.selectionChanging.emit(args);\n\n if (args.cancel) {\n return;\n }\n\n this.setSelection(newSelection);\n this._value = newSelection.value;\n\n if (event) {\n this.toggleDirective.close();\n }\n\n this.cdr.detectChanges();\n this._onChangeCallback(this.value);\n }\n\n /** @hidden @internal */\n public getFirstItemElement(): HTMLElement {\n return this.children.first.element.nativeElement;\n }\n\n /**\n * Opens the select\n *\n * ```typescript\n * this.select.open();\n * ```\n */\n public override open(overlaySettings?: OverlaySettings) {\n if (this.disabled || this.items.length === 0) {\n return;\n }\n if (!this.selectedItem) {\n this.navigateFirst();\n }\n\n super.open(Object.assign({}, this._overlayDefaults, this.overlaySettings, overlaySettings));\n }\n\n public inputGroupClick(event: MouseEvent, overlaySettings?: OverlaySettings) {\n const targetElement = event.target as HTMLElement;\n\n if (this.hintElement && targetElement.contains(this.hintElement.nativeElement)) {\n return;\n }\n this.toggle(Object.assign({}, this._overlayDefaults, this.overlaySettings, overlaySettings));\n }\n\n /** @hidden @internal */\n public ngAfterContentInit() {\n this._overlayDefaults = {\n target: this.getEditElement(),\n modal: false,\n positionStrategy: new SelectPositioningStrategy(this),\n scrollStrategy: new AbsoluteScrollStrategy(),\n excludeFromOutsideClick: [this.inputGroup.element.nativeElement as HTMLElement]\n };\n const changes$ = this.children.changes.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.setSelection(this.items.find(x => x.value === this.value));\n this.cdr.detectChanges();\n });\n Promise.resolve().then(() => {\n if (!changes$.closed) {\n this.children.notifyOnChanges();\n }\n });\n }\n\n /**\n * Event handlers\n *\n * @hidden @internal\n */\n public handleOpening(e: ToggleViewCancelableEventArgs) {\n const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel };\n this.opening.emit(args);\n\n e.cancel = args.cancel;\n if (args.cancel) {\n return;\n }\n }\n\n /** @hidden @internal */\n public override onToggleContentAppended(event: ToggleViewEventArgs) {\n const info = this.overlayService.getOverlayById(event.id);\n if (info?.settings?.positionStrategy instanceof SelectPositioningStrategy) {\n return;\n }\n super.onToggleContentAppended(event);\n }\n\n /** @hidden @internal */\n public handleOpened() {\n this.updateItemFocus();\n this.opened.emit({ owner: this });\n }\n\n /** @hidden @internal */\n public handleClosing(e: ToggleViewCancelableEventArgs) {\n const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel };\n this.closing.emit(args);\n e.cancel = args.cancel;\n }\n\n /** @hidden @internal */\n public handleClosed() {\n this.focusItem(false);\n this.closed.emit({ owner: this });\n }\n\n /** @hidden @internal */\n public onBlur(): void {\n this._onTouchedCallback();\n if (this.ngControl && this.ngControl.invalid) {\n this.input.valid = IgxInputState.INVALID;\n } else {\n this.input.valid = IgxInputState.INITIAL;\n }\n }\n\n /** @hidden @internal */\n public onFocus(): void {\n this._onTouchedCallback();\n }\n\n /**\n * @hidden @internal\n */\n public override ngOnInit() {\n this.ngControl = this._injector.get<NgControl>(NgControl, null);\n }\n\n /**\n * @hidden @internal\n */\n public override ngAfterViewInit() {\n super.ngAfterViewInit();\n\n if (this.ngControl) {\n this.ngControl.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged.bind(this));\n this.manageRequiredAsterisk();\n }\n\n this.cdr.detectChanges();\n }\n\n /** @hidden @internal */\n public ngAfterContentChecked() {\n if (this.inputGroup && this.prefixes?.length > 0) {\n this.inputGroup.prefixes = this.prefixes;\n }\n\n if (this.inputGroup) {\n const suffixesArray = this.suffixes?.toArray() ?? [];\n const internalSuffixesArray = this.internalSuffixes?.toArray() ?? [];\n const mergedSuffixes = new QueryList<IgxSuffixDirective>();\n mergedSuffixes.reset([\n ...suffixesArray,\n ...internalSuffixesArray\n ]);\n this.inputGroup.suffixes = mergedSuffixes;\n }\n }\n\n /** @hidden @internal */\n public get toggleIcon(): string {\n return this.collapsed ? 'input_expand' : 'input_collapse';\n }\n\n /**\n * @hidden @internal\n * Prevent input blur - closing the items container on Header/Footer Template click.\n */\n public mousedownHandler(event) {\n event.preventDefault();\n }\n\n protected onStatusChanged() {\n this.manageRequiredAsterisk();\n if (this.ngControl && !this.disabled && this.isTouchedOrDirty) {\n if (this.hasValidators && this.inputGroup.isFocused) {\n this.input.valid = this.ngControl.valid ? IgxInputState.VALID : IgxInputState.INVALID;\n } else {\n // B.P. 18 May 2021: IgxDatePicker does not reset its state upon resetForm #9526\n this.input.valid = this.ngControl.valid ? IgxInputState.INITIAL : IgxInputState.INVALID;\n }\n } else {\n this.input.valid = IgxInputState.INITIAL;\n }\n }\n\n private get isTouchedOrDirty(): boolean {\n return (this.ngControl.control.touched || this.ngControl.control.dirty);\n }\n\n private get hasValidators(): boolean {\n return (!!this.ngControl.control.validator || !!this.ngControl.control.asyncValidator);\n }\n\n protected override navigate(direction: Navigate, currentIndex?: number) {\n if (this.collapsed && this.selectedItem) {\n this.navigateItem(this.selectedItem.itemIndex);\n }\n super.navigate(direction, currentIndex);\n }\n\n protected manageRequiredAsterisk(): void {\n const hasRequiredHTMLAttribute = this.elementRef.nativeElement.hasAttribute('required');\n let isRequired = false;\n\n if (this.ngControl && this.ngControl.control.validator) {\n const error = this.ngControl.control.validator({} as AbstractControl);\n isRequired = !!(error && error.required);\n }\n\n this.inputGroup.isRequired = isRequired;\n\n if (this.input?.nativeElement) {\n this.input.nativeElement.setAttribute('aria-required', isRequired.toString());\n }\n\n // Handle validator removal case\n if (!isRequired && !hasRequiredHTMLAttribute) {\n this.input.valid = IgxInputState.INITIAL;\n }\n\n this.cdr.markForCheck();\n }\n\n private setSelection(item: IgxDropDownItemBaseDirective) {\n if (item && item.value !== undefined && item.value !== null) {\n this.selection.set(this.id, new Set([item]));\n } else {\n this.selection.clear(this.id);\n }\n }\n}\n\n","<igx-input-group #inputGroup class=\"input-group\" (click)=\"inputGroupClick($event)\" [type]=\"type === 'search' ? 'line' : type\">\n <ng-container ngProjectAs=\"[igxLabel]\">\n <ng-content select=\"[igxLabel]\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-prefix\">\n <ng-content select=\"igx-prefix,[igxPrefix]\"></ng-content>\n </ng-container>\n <input #input class=\"input\" type=\"text\" igxInput [igxSelectItemNavigation]=\"this\"\n [disabled]=\"disabled\"\n readonly=\"true\"\n [igxReadOnlyInput]=\"false\"\n [attr.placeholder]=\"this.placeholder\"\n [value]=\"this.selectionValue\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-labelledby]=\"this.label?.id\"\n [attr.aria-expanded]=\"!this.collapsed\"\n [attr.aria-owns]=\"this.listId\"\n [attr.aria-activedescendant]=\"!this.collapsed ? this.focusedItem?.id : null\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n />\n <ng-container ngProjectAs=\"igx-suffix\">\n <ng-content select=\"igx-suffix,[igxSuffix]\"></ng-content>\n </ng-container>\n <igx-suffix class=\"igx-select__toggle-button\">\n @if (toggleIconTemplate) {\n <ng-container *ngTemplateOutlet=\"toggleIconTemplate; context: {$implicit: this.collapsed}\"></ng-container>\n }\n @if (!toggleIconTemplate) {\n <igx-icon family=\"default\" [name]=\"toggleIcon\"></igx-icon>\n }\n </igx-suffix>\n <ng-container ngProjectAs=\"igx-hint, [igxHint]\" >\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n </ng-container>\n</igx-input-group>\n<div igxToggle class=\"igx-drop-down__list\" (mousedown)=\"mousedownHandler($event);\"\n (appended)=\"onToggleContentAppended($event)\"\n (opening)=\"handleOpening($event)\"\n (opened)=\"handleOpened()\"\n (closing)=\"handleClosing($event)\"\n (closed)=\"handleClosed()\">\n\n @if (headerTemplate) {\n <div class=\"igx-drop-down__select-header\">\n <ng-content *ngTemplateOutlet=\"headerTemplate\"></ng-content>\n </div>\n }\n\n <!-- #7436 LMB scrolling closes items container - unselectable attribute is IE specific -->\n <div #scrollContainer class=\"igx-drop-down__list-scroll\" unselectable=\"on\" [style.maxHeight]=\"maxHeight\"\n [attr.id]=\"this.listId\" role=\"listbox\" [attr.aria-labelledby]=\"this.label?.id\">\n <ng-content select=\"igx-select-item, igx-select-item-group\"></ng-content>\n </div>\n\n @if (footerTemplate) {\n <div class=\"igx-drop-down__select-footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate\"></ng-container>\n </div>\n }\n</div>\n","import { IgxHintDirective, IgxLabelDirective, IgxPrefixDirective, IgxSuffixDirective } from 'igniteui-angular/input-group';\nimport { IgxSelectGroupComponent } from './select-group.component';\nimport { IgxSelectItemComponent } from './select-item.component';\nimport { IgxSelectComponent, IgxSelectFooterDirective, IgxSelectHeaderDirective, IgxSelectToggleIconDirective } from './select.component';\n\nexport * from './select-group.component';\nexport * from './select-item.component';\nexport * from './select.component';\n\n/* NOTE: Select directives collection for ease-of-use import in standalone components scenario */\nexport const IGX_SELECT_DIRECTIVES = [\n IgxSelectComponent,\n IgxSelectItemComponent,\n IgxSelectGroupComponent,\n IgxSelectHeaderDirective,\n IgxSelectFooterDirective,\n IgxSelectToggleIconDirective,\n IgxLabelDirective,\n IgxPrefixDirective,\n IgxSuffixDirective,\n IgxHintDirective\n] as const;\n","import { NgModule } from '@angular/core';\nimport { IGX_SELECT_DIRECTIVES } from './public_api';\n\n/**\n * @hidden\n * @deprecated\n * IMPORTANT: The following is NgModule exported for backwards-compatibility before standalone components\n */\n@NgModule({\n imports: [\n ...IGX_SELECT_DIRECTIVES\n ],\n exports: [\n ...IGX_SELECT_DIRECTIVES\n ]\n})\nexport class IgxSelectModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["i1.IgxSelectComponent","i2.IgxSelectItemComponent","i3.IgxSelectGroupComponent","i1.IgxSelectHeaderDirective","i1.IgxSelectFooterDirective","i1.IgxSelectToggleIconDirective"],"mappings":"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