1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import {Component, EventEmitter, Input, Output} from '@angular/core'; 17import {MatSelectChange} from '@angular/material/select'; 18 19@Component({ 20 selector: 'select-with-filter', 21 template: ` 22 <mat-form-field 23 [style]="getOuterFormFieldStyle()" 24 [style.text-align]="'unset'" 25 [appearance]="appearance" 26 [class]="formFieldClass" 27 [class.mat-body-2]="!select.value || select.value.length === 0"> 28 <mat-label>{{ label }}</mat-label> 29 <mat-select 30 (opened)="filter.focus()" 31 (closed)="onSelectClosed()" 32 (selectionChange)="onSelectChange($event)" 33 [multiple]="true" 34 #select> 35 <mat-form-field class="select-filter" [style]="getInnerFormFieldStyle()"> 36 <mat-label>Filter options</mat-label> 37 <input matInput #filter [(ngModel)]="filterString" /> 38 </mat-form-field> 39 <mat-option 40 *ngFor="let option of options" 41 [value]="option" 42 [class.hidden-option]="hideOption(option)"> 43 {{ option }} 44 </mat-option> 45 </mat-select> 46 </mat-form-field> 47 `, 48 styles: [ 49 ` 50 mat-form-field { 51 width: 100%; 52 } 53 54 .hidden-option { 55 display: none; 56 } 57 `, 58 ], 59}) 60export class SelectWithFilterComponent { 61 @Input() label: string = ''; 62 @Input() options: string[] = []; 63 @Input() outerFilterWidth = '100px'; 64 @Input() innerFilterWidth = '100'; 65 @Input() flex = 'none'; 66 @Input() appearance = ''; 67 @Input() formFieldClass = ''; 68 69 @Output() readonly selectChange = new EventEmitter<MatSelectChange>(); 70 71 filterString: string = ''; 72 73 onSelectChange(event: MatSelectChange) { 74 this.selectChange.emit(event); 75 } 76 77 getOuterFormFieldStyle() { 78 return { 79 flex: this.flex, 80 width: this.outerFilterWidth, 81 }; 82 } 83 84 getInnerFormFieldStyle() { 85 return { 86 flex: 'none', 87 paddingTop: '2px', 88 paddingLeft: '10px', 89 paddingRight: '20px', 90 width: this.innerFilterWidth + 'px', 91 }; 92 } 93 94 onSelectClosed() { 95 this.filterString = ''; 96 } 97 98 hideOption(option: string) { 99 return !option.toLowerCase().includes(this.filterString.toLowerCase()); 100 } 101} 102