xref: /aosp_15_r20/development/tools/winscope/src/viewers/components/select_with_filter_component.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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