feat: refactor search input to improve UI and accessibility in category management dialog

Entire-Checkpoint: 55bde394786b
This commit is contained in:
4gray committed 2026-04-04 20:29:42 +02:00
1 parent 0661bf08b5
commit c935c8616d
3 files changed
+84 -29

No files matched your search

@@ -32,26 +32,29 @@
</div>
</div>
<mat-form-field
appearance="outline"
class="search-field"
subscriptSizing="dynamic"
>
<mat-icon matPrefix>search</mat-icon>
<label class="search-inline">
<mat-icon class="search-inline__icon">search</mat-icon>
<input
matInput
[ngModel]="searchTerm()"
(ngModelChange)="searchTerm.set($event)"
placeholder="{{
'XTREAM.CATEGORY_MANAGEMENT.SEARCH_PLACEHOLDER' | translate
}}"
type="search"
spellcheck="false"
[value]="searchTerm()"
(input)="searchTerm.set($any($event.target).value)"
[placeholder]="
'XTREAM.CATEGORY_MANAGEMENT.SEARCH_PLACEHOLDER'
| translate
"
/>
@if (searchTerm()) {
<button matSuffix mat-icon-button (click)="clearSearch()">
<button
type="button"
mat-icon-button
class="search-inline__clear"
(click)="clearSearch()"
>
<mat-icon>close</mat-icon>
</button>
}
</mat-form-field>
</label>
<div class="categories-list">
@for (category of filteredCategories(); track category.id) {
@@ -43,17 +43,74 @@
}
}
.search-field {
width: 100%;
.search-inline {
display: flex;
align-items: center;
gap: 8px;
padding: 0 10px;
min-height: 36px;
border-radius: 10px;
border: 1px solid var(--app-search-border, var(--mat-sys-outline-variant));
background: var(--app-search-bg, var(--mat-sys-surface-container));
cursor: text;
transition:
border-color 0.15s ease,
box-shadow 0.15s ease;
mat-icon[matPrefix] {
margin-right: 8px;
&:focus-within {
border-color: var(--mat-sys-primary);
box-shadow: 0 0 0 3px
color-mix(in srgb, var(--mat-sys-primary) 12%, transparent);
}
}
.search-inline__icon {
font-size: 18px;
width: 18px;
height: 18px;
color: var(--mat-sys-on-surface-variant);
flex-shrink: 0;
}
.search-inline input {
flex: 1;
border: none;
outline: none;
background: transparent;
color: var(--mat-sys-on-surface);
font: inherit;
font-size: 0.84rem;
width: 100%;
min-width: 0;
&::placeholder {
color: var(--mat-sys-on-surface-variant);
opacity: 0.6;
}
&::-webkit-search-cancel-button {
display: none;
}
}
.search-inline__clear {
width: 24px;
height: 24px;
min-width: 24px;
line-height: 24px;
flex-shrink: 0;
padding: 0;
mat-icon {
font-size: 16px;
width: 16px;
height: 16px;
}
}
.categories-list {
height: 450px;
flex: 1;
min-height: 200px;
overflow-y: auto;
border: 1px solid var(--mat-sys-outline-variant);
border-radius: 8px;
@@ -62,9 +119,10 @@
.category-item {
display: flex;
align-items: center;
padding: 2px 10px;
padding: 0 10px;
min-height: 30px;
cursor: pointer;
gap: 8px;
gap: 6px;
transition: background-color 0.12s ease;
&:hover {
@@ -76,7 +134,7 @@
}
mat-checkbox {
--mdc-checkbox-state-layer-size: 32px;
--mdc-checkbox-state-layer-size: 28px;
}
}
@@ -99,7 +157,7 @@
.mat-mdc-dialog-content {
min-width: 480px;
max-width: 600px;
max-height: 75vh !important;
max-height: 85vh !important;
}
}
@@ -1,5 +1,4 @@
import { Component, computed, inject, OnInit, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import {
@@ -7,9 +6,7 @@ import {
MatDialogModule,
MatDialogRef,
} from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSnackBar } from '@angular/material/snack-bar';
import { TranslatePipe } from '@ngx-translate/core';
@@ -32,11 +29,8 @@ interface CategoryWithSelection extends XCategoryFromDb {
MatDialogModule,
MatButtonModule,
MatCheckboxModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatProgressSpinnerModule,
FormsModule,
TranslatePipe,
],
templateUrl: './category-management-dialog.component.html',