[ACS-10271][ACS-10236] a11y - Search filters have no visible labels (#11302)

* [ACS-10271][ACS-10236] a11y - Search filters have no visible labels

* [ACS-10271] sonar fix

* [ACS-10271] cr fix
This commit is contained in:
Mykyta Maliarchuk
2025-10-24 12:03:16 +02:00
committed by GitHub
parent f152953cc9
commit 160b12993f
8 changed files with 121 additions and 175 deletions
+10 -3
View File
@@ -428,7 +428,8 @@
"IN_LAST_LABELS": {
"DAYS": "Days",
"WEEKS": "Weeks",
"MONTHS": "Months"
"MONTHS": "Months",
"QUANTITY": "Quantity"
},
"IN_LAST_DISPLAY_LABELS": {
"DAYS": "In the last {{value}} days",
@@ -437,7 +438,8 @@
},
"BETWEEN_PLACEHOLDERS": {
"START_DATE": "Start Date",
"END_DATE": "End Date"
"END_DATE": "End Date",
"DATE_RANGE": "Date Range"
},
"ERROR": {
"IN_LAST": "Value required",
@@ -468,7 +470,12 @@
"GB": "GB"
},
"FILE_TYPE": "File Type",
"FILE_TYPE_PLACEHOLDER": "Add file type"
"FILE_TYPE_PLACEHOLDER": "Add file type",
"ACCESSIBILITY": {
"CONDITION": "Condition",
"SIZE_VALUE": "File size value",
"UNIT": "Unit"
}
}
},
"PERMISSION": {
@@ -1,4 +1,5 @@
<mat-form-field class="adf-chip-list" appearance="outline">
<mat-label>{{ placeholder | translate }}</mat-label>
<mat-chip-grid #chipList [attr.aria-label]="'SEARCH.FILTER.ARIA-LABEL.OPTIONS-SELECTION' | translate">
<mat-chip-row
class="adf-option-chips adf-autocomplete-added-option-chips"
@@ -9,14 +9,17 @@
<mat-radio-button [value]="DateRangeType.IN_LAST" data-automation-id="date-range-in-last">
{{ 'SEARCH.DATE_RANGE_ADVANCED.OPTIONS.IN_LAST' | translate }}
</mat-radio-button>
<mat-form-field class="adf-search-date-range-form-field adf-search-date-range-input-field" subscriptSizing="dynamic">
<mat-form-field class="adf-search-date-range-form-field adf-search-date-range-input-field" subscriptSizing="dynamic" floatLabel="always">
<mat-label id="adf-search-date-range-quantity-label">{{ 'SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.QUANTITY' | translate }}</mat-label>
<input matInput [attr.aria-label]="'SEARCH.DATE_RANGE_ADVANCED.ARIA_LABEL.NUMBER_INPUT' | translate"
aria-labelledby="adf-search-date-range-quantity-label"
type="number" min="1" formControlName="inLastValue"
data-automation-id="date-range-in-last-input" (input)="narrowDownAllowedCharacters($event)"
(keydown)="preventIncorrectNumberCharacters($event)">
<mat-error *ngIf="form.controls.inLastValue.errors?.required">{{ 'SEARCH.DATE_RANGE_ADVANCED.ERROR.IN_LAST' | translate }}</mat-error>
</mat-form-field>
<mat-form-field class="adf-search-date-range-form-field adf-search-date-range-form-field-select" subscriptSizing="dynamic">
<mat-label>{{ 'SEARCH.SEARCH_PROPERTIES.ACCESSIBILITY.UNIT' | translate }}</mat-label>
<mat-select formControlName="inLastValueType" data-automation-id="date-range-in-last-dropdown">
<mat-option data-automation-id="date-range-in-last-option-days" [value]="InLastDateType.DAYS">{{ 'SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.DAYS' | translate }}</mat-option>
<mat-option data-automation-id="date-range-in-last-option-weeks" [value]="InLastDateType.WEEKS">{{ 'SEARCH.DATE_RANGE_ADVANCED.IN_LAST_LABELS.WEEKS' | translate }}</mat-option>
@@ -28,7 +31,8 @@
<mat-radio-button [value]="DateRangeType.BETWEEN" data-automation-id="date-range-between">
{{ 'SEARCH.DATE_RANGE_ADVANCED.OPTIONS.BETWEEN' | translate }}
</mat-radio-button>
<mat-form-field class="adf-search-date-range-form-field" subscriptSizing="dynamic">
<mat-form-field class="adf-search-date-range-form-field" subscriptSizing="dynamic" floatLabel="always">
<mat-label>{{ 'SEARCH.DATE_RANGE_ADVANCED.BETWEEN_PLACEHOLDERS.DATE_RANGE' | translate }}</mat-label>
<mat-date-range-input [rangePicker]="$any(picker)" [max]="convertedMaxDate">
<input matStartDate placeholder="{{ 'SEARCH.DATE_RANGE_ADVANCED.BETWEEN_PLACEHOLDERS.START_DATE' | translate }}"
data-automation-id="date-range-between-start-input" [formControl]="betweenStartDateFormControl" (change)="dateChanged($event, betweenStartDateFormControl)">
@@ -32,14 +32,6 @@ adf-search-date-range {
padding-left: 10px;
flex: 1;
margin-bottom: 12px;
#{ms.$mat-form-field-flex} {
align-items: center;
#{ms.$mat-form-field-infix} {
padding: 0.375em 0 4px;
}
}
}
}
}
@@ -44,10 +44,6 @@
min-width: 320px;
border-radius: 12px;
&:has(.adf-search-properties-file-size-operator) {
min-width: 365px;
}
@include mat.elevation(2);
}
}
@@ -1,48 +1,61 @@
<form [formGroup]="form" class="adf-search-properties-form">
<div class="adf-search-properties-file-size-container">
<label
for="adf-search-properties-file-size"
class="adf-search-properties-file-size-label">
<fieldset aria-labelledby="file-size-label">
<legend id="file-size-label" class="adf-search-properties-file-size-label">
{{ 'SEARCH.SEARCH_PROPERTIES.FILE_SIZE' | translate }}
</label>
<mat-form-field
[style.width.px]="fileSizeOperatorsMaxWidth"
subscriptSizing="dynamic"
class="adf-search-properties-file-size-operator">
<mat-select
data-automation-id="adf-search-properties-file-size-operator-select"
[formControl]="form.controls.fileSizeOperator"
#fileSizeOperatorSelect>
<mat-option
*ngFor="let fileSizeOperator of fileSizeOperators"
[value]="fileSizeOperator">
{{ fileSizeOperator | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<input
[formControl]="form.controls.fileSize"
type="number"
min="0"
step="any"
(input)="narrowDownAllowedCharacters($event)"
(keydown)="preventIncorrectNumberCharacters($event)"
id="adf-search-properties-file-size"
[placeholder]="'SEARCH.SEARCH_PROPERTIES.FILE_SIZE_PLACEHOLDER' | translate"
(blur)="clearNumberFieldWhenInvalid($event)"
data-automation-id="adf-search-properties-file-size-input" />
<mat-form-field class="adf-search-properties-file-size-unit" subscriptSizing="dynamic">
<mat-select
[formControl]="form.controls.fileSizeUnit"
data-automation-id="adf-search-properties-file-size-unit-select">
<mat-option
*ngFor="let fileSizeUnit of fileSizeUnits"
[value]="fileSizeUnit">
{{ fileSizeUnit.abbreviation | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</legend>
<div class="adf-search-properties-file-size-container">
<mat-form-field
class="adf-search-properties-form-field"
[style.flex]="'0 0 ' + fileSizeOperatorsMaxWidth + 'px'"
subscriptSizing="dynamic"
data-automation-id="adf-search-properties-file-size-operator"
appearance="outline">
<mat-label>{{ 'SEARCH.SEARCH_PROPERTIES.ACCESSIBILITY.CONDITION' | translate }}</mat-label>
<mat-select
data-automation-id="adf-search-properties-file-size-operator-select"
[formControl]="form.controls.fileSizeOperator"
#fileSizeOperatorSelect>
<mat-option
*ngFor="let fileSizeOperator of fileSizeOperators"
[value]="fileSizeOperator">
{{ fileSizeOperator | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="adf-search-properties-form-field" appearance="outline" floatLabel="always">
<mat-label>{{ 'SEARCH.SEARCH_PROPERTIES.ACCESSIBILITY.SIZE_VALUE' | translate }}</mat-label>
<input
matInput
[formControl]="form.controls.fileSize"
type="number"
min="0"
step="any"
(input)="narrowDownAllowedCharacters($event)"
(keydown)="preventIncorrectNumberCharacters($event)"
id="adf-search-properties-file-size"
[placeholder]="'SEARCH.SEARCH_PROPERTIES.FILE_SIZE_PLACEHOLDER' | translate"
(blur)="clearNumberFieldWhenInvalid($event)"
data-automation-id="adf-search-properties-file-size-input"/>
</mat-form-field>
<mat-form-field
class="adf-search-properties-form-field"
data-automation-id="adf-search-properties-file-size-unit"
subscriptSizing="dynamic"
appearance="outline">
<mat-label>{{ 'SEARCH.SEARCH_PROPERTIES.ACCESSIBILITY.UNIT' | translate }}</mat-label>
<mat-select
[attr.aria-label]="'SEARCH.SEARCH_PROPERTIES.ACCESSIBILITY.UNIT' | translate"
[formControl]="form.controls.fileSizeUnit"
data-automation-id="adf-search-properties-file-size-unit-select">
<mat-option
*ngFor="let fileSizeUnit of fileSizeUnits"
[value]="fileSizeUnit">
{{ fileSizeUnit.abbreviation | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</fieldset>
<p class="adf-search-properties-file-type-label">{{ 'SEARCH.SEARCH_PROPERTIES.FILE_TYPE' | translate }}</p>
<adf-search-chip-autocomplete-input
[autocompleteOptions]="autocompleteOptions"
@@ -53,5 +66,5 @@
[compareOption]="compareFileExtensions"
[formatChipValue]="getExtensionWithoutDot"
[filter]="filterExtensions"
placeholder="SEARCH.SEARCH_PROPERTIES.FILE_TYPE" />
placeholder="SEARCH.SEARCH_PROPERTIES.FILE_TYPE"/>
</form>
@@ -3,133 +3,54 @@
adf-search-properties {
.adf-search-properties-form {
.adf-search-properties-file-size-container {
.adf-search-properties-file-size-label {
margin-top: 4px;
display: block;
}
fieldset {
padding: 0;
margin: 0;
border: none;
}
#{ms.$mat-text-field-no-label} {
#{ms.$mat-form-field-infix} {
padding-top: 9px;
padding-bottom: 9px;
display: inline-block;
}
}
.adf-search-properties-file-size-label {
margin-top: 4px;
margin-bottom: 10px;
display: block;
}
.adf-search-properties-file-type-label {
margin-top: 10px;
margin-bottom: 6px;
}
.adf-search-properties-file-size-container {
width: 370px;
display: flex;
#{ms.$mat-form-field-infix} {
height: 37.5px;
min-height: 37.5px;
display: inline-block;
padding-top: 9px;
}
#{ms.$mat-select-trigger} {
height: 17.5px;
}
#{ms.$mat-select-arrow-wrapper} {
width: 16px;
}
#{ms.$mat-line-ripple} {
&::before {
display: none;
}
}
#{ms.$mat-select-arrow} {
margin-left: 5px;
}
#{ms.$mat-form-field} {
margin-bottom: 18px;
}
}
adf-search-chip-autocomplete-input {
display: block;
#{ms.$mat-text-field-outlined} {
&-start,
&-end {
border-top: 1px solid var(--adf-theme-mat-grey-color-a400);
border-bottom: 1px solid var(--adf-theme-mat-grey-color-a400);
}
&-start {
border-left: 1px solid var(--adf-theme-mat-grey-color-a400);
}
&-end {
border-right: 1px solid var(--adf-theme-mat-grey-color-a400);
}
padding: 0 9px;
}
#{ms.$mat-focused} {
#{ms.$mat-text-field-outlined} {
outline: 2px auto -webkit-focus-ring-color;
.adf-search-properties-form-field {
width: 100%;
display: block;
flex: 1;
&:nth-child(1) {
min-width: 115px;
}
}
#{ms.$mat-form-field-appearance-outline} {
#{ms.$mat-text-field-outlined-thick} {
#{ms.$mat-text-field-outlined} {
&-start,
&-end {
border-width: 1px;
}
}
&:nth-child(2) {
margin: 0 8px;
}
}
#{ms.$mat-notched-outline-leading} {
border-color: var(--adf-theme-foreground-text-color-027);
}
#{ms.$mat-notched-outline-trailing} {
border-color: var(--adf-theme-foreground-text-color-027);
&:nth-child(3) {
max-width: 90px;
}
}
}
}
input,
.mat-form-field-infix.mat-form-field-infix {
height: 25px;
border: 1px solid var(--adf-theme-mat-grey-color-a400);
border-radius: 5px;
margin-top: 5px;
padding: 5px;
font-size: 14px;
color: var(--adf-theme-foreground-text-color);
margin-left: 8px;
margin-right: 8px;
}
.adf-search-properties-file-size-operator,
.adf-search-properties-file-size-unit {
#{ms.$mat-form-field-infix} {
border: 1px solid var(--adf-theme-mat-grey-color-a400);
border-radius: 5px;
padding: 9px;
}
&#{ms.$mat-focused} {
#{ms.$mat-form-field-infix} {
outline: 2px auto -webkit-focus-ring-color;
}
}
}
.adf-search-properties-file-size-unit {
width: 78px;
}
.adf-search-properties-file-type-label {
margin-top: 10px;
margin-bottom: 6px;
}
}
.adf-search-filter-chip-menu-panel-properties {
max-width: unset;
}
@@ -30,13 +30,22 @@ import { AutocompleteOption } from '../../models/autocomplete-option.interface';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { SearchChipAutocompleteInputComponent } from '../search-chip-autocomplete-input';
import { map } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-search-properties',
imports: [CommonModule, ReactiveFormsModule, TranslatePipe, MatFormFieldModule, MatSelectModule, SearchChipAutocompleteInputComponent],
imports: [
CommonModule,
ReactiveFormsModule,
TranslatePipe,
MatFormFieldModule,
MatSelectModule,
MatInputModule,
SearchChipAutocompleteInputComponent
],
templateUrl: './search-properties.component.html',
styleUrls: ['./search-properties.component.scss'],
encapsulation: ViewEncapsulation.None
@@ -97,7 +106,10 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
private readonly destroyRef = inject(DestroyRef);
constructor(private formBuilder: FormBuilder, private translateService: TranslateService) {}
constructor(
private readonly formBuilder: FormBuilder,
private readonly translateService: TranslateService
) {}
ngOnInit() {
if (this.settings) {