79730: Keyboard navigation for expandable filter facets

This commit is contained in:
Yura Bondarenko
2021-06-01 12:42:40 +02:00
parent 3e86efc66a
commit abe26ce9f8
3 changed files with 63 additions and 11 deletions

View File

@@ -1,17 +1,19 @@
<div class="facet-filter d-block mb-3 p-3" *ngIf="active$ | async"> <div class="facet-filter d-block mb-3 p-3" *ngIf="active$ | async"
<div (click)="toggle()" class="filter-name"> [id]="regionId" [attr.aria-labelledby]="toggleId" [ngClass]="{ 'focus': focusBox }" role="region">
<button (click)="toggle()" (focusin)="focusBox = true" (focusout)="focusBox = false"
class="filter-name d-flex" [attr.aria-controls]="regionId" [id]="toggleId" [attr.aria-expanded]="false">
<h5 class="d-inline-block mb-0"> <h5 class="d-inline-block mb-0">
{{'search.filters.filter.' + filter.name + '.head'| translate}} {{'search.filters.filter.' + filter.name + '.head'| translate}}
</h5> </h5>
<span class="filter-toggle fas float-right" <span class="filter-toggle flex-grow-1 fas p-auto"
[ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'" [ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'"
[title]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate" [title]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate"
[attr.aria-label]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate"> [attr.aria-label]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate">
</span> </span>
</div> </button>
<div [@slide]="(collapsed$ | async) ? 'collapsed' : 'expanded'" <div [@slide]="(collapsed$ | async) ? 'collapsed' : 'expanded'"
(@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)" (@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)"
class="search-filter-wrapper" [ngClass]="{'closed' : closed}"> class="search-filter-wrapper" [ngClass]="{ 'closed' : closed, 'notab': notab }">
<ds-search-facet-filter-wrapper <ds-search-facet-filter-wrapper
[filterConfig]="filter" [filterConfig]="filter"
[inPlaceSearch]="inPlaceSearch"> [inPlaceSearch]="inPlaceSearch">

View File

@@ -1,10 +1,36 @@
:host .facet-filter { :host .facet-filter {
border: 1px solid var(--bs-light); border: 1px solid var(--bs-light);
cursor: pointer; cursor: pointer;
.search-filter-wrapper.closed { line-height: 0;
.search-filter-wrapper {
line-height: var(--bs-line-height-base);
&.closed {
overflow: hidden; overflow: hidden;
} }
&.notab {
visibility: hidden;
}
}
.filter-toggle { .filter-toggle {
line-height: var(--bs-line-height-base); line-height: var(--bs-line-height-base);
text-align: right;
position: relative;
top: -0.125rem; // Fix weird outline shape in Chrome
}
> button {
appearance: none;
border: 0;
padding: 0;
background: transparent;
width: 100%;
outline: none !important;
}
&.focus {
outline: none;
box-shadow: var(--bs-input-btn-focus-box-shadow);
} }
} }

View File

@@ -37,6 +37,16 @@ export class SearchFilterComponent implements OnInit {
*/ */
closed: boolean; closed: boolean;
/**
* True when the filter controls should be hidden & removed from the tablist
*/
notab: boolean;
/**
* True when the filter toggle button is focused
*/
focusBox: boolean = false;
/** /**
* Emits true when the filter is currently collapsed in the store * Emits true when the filter is currently collapsed in the store
*/ */
@@ -112,6 +122,9 @@ export class SearchFilterComponent implements OnInit {
if (event.fromState === 'collapsed') { if (event.fromState === 'collapsed') {
this.closed = false; this.closed = false;
} }
if (event.toState === 'collapsed') {
this.notab = true;
}
} }
/** /**
@@ -122,6 +135,17 @@ export class SearchFilterComponent implements OnInit {
if (event.toState === 'collapsed') { if (event.toState === 'collapsed') {
this.closed = true; this.closed = true;
} }
if (event.fromState === 'collapsed') {
this.notab = false;
}
}
get regionId(): string {
return `search-filter-region-${this.constructor['ɵcmp'].id}`;
}
get toggleId(): string {
return `search-filter-toggle-${this.constructor['ɵcmp'].id}`;
} }
/** /**