mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Fixes #12639 It's now possible to tab to each filter's actions and interact with them via the keyboard. In order to get the actions to show/hide on both mouse hover and action focus I had to create a new filter-pill component that could manage a bit of state to track whether the user was interacting with a given pill or not.
This commit is contained in:
parent
fdfd477ccf
commit
89df1620f9
6 changed files with 135 additions and 51 deletions
|
@ -26,39 +26,15 @@
|
|||
class="filter-bar"
|
||||
ng-show="filters.length || showAddFilterButton()"
|
||||
>
|
||||
<div
|
||||
class="filter"
|
||||
ng-class="{ negate: filter.meta.negate, disabled: filter.meta.disabled }"
|
||||
<filter-pill
|
||||
ng-repeat="filter in filters track by $index"
|
||||
data-test-subj="filter filter-{{ filter.meta.disabled ? 'disabled' : 'enabled' }} {{ filter.meta.key ? 'filter-key-' + filter.meta.key : '' }} {{ filter.meta.value ? 'filter-value-' + filter.meta.value : '' }}"
|
||||
>
|
||||
<div class="filter-description">
|
||||
<span ng-if="filter.$state.store == 'globalState'"><i class="fa fa-fw fa-thumb-tack pinned"></i></span>
|
||||
<span ng-if="filter.meta.alias">{{ filter.meta.alias }}</span>
|
||||
<span ng-if="!filter.meta.alias">{{ filter.meta.key }}:</span>
|
||||
<span ng-if="!filter.meta.alias">"{{ filter.meta.value }}"</span>
|
||||
</div>
|
||||
<div class="filter-actions">
|
||||
<a class="action filter-toggle" ng-click="toggleFilter(filter)" data-test-subj="disableFilter-{{ filter.meta.key }}">
|
||||
<i ng-show="filter.meta.disabled" class="fa fa-fw fa-square-o disabled"></i>
|
||||
<i ng-hide="filter.meta.disabled" class="fa fa-fw fa-check-square-o enabled"></i>
|
||||
</a>
|
||||
<a class="action filter-pin" ng-click="pinFilter(filter)" data-test-subj="pinFilter-{{ filter.meta.key }}">
|
||||
<i ng-show="filter.$state.store == 'globalState'" class="fa fa-fw fa-thumb-tack pinned"></i>
|
||||
<i ng-hide="filter.$state.store == 'globalState'" class="fa fa-fw fa-thumb-tack fa-rotate-270 unpinned"></i>
|
||||
</a>
|
||||
<a class="action filter-invert" ng-click="invertFilter(filter)" data-test-subj="invertFilter-{{ filter.meta.key }}">
|
||||
<i ng-show="filter.meta.negate" class="fa fa-fw fa-search-plus negative"></i>
|
||||
<i ng-hide="filter.meta.negate" class="fa fa-fw fa-search-minus positive"></i>
|
||||
</a>
|
||||
<a class="action filter-remove" ng-click="deleteFilter(filter)">
|
||||
<i class="fa fa-fw fa-trash" data-test-subj="removeFilter-{{ filter.meta.key }}"></i>
|
||||
</a>
|
||||
<a class="action filter-edit" ng-click="editFilter(filter)">
|
||||
<i class="fa fa-fw fa-edit"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
filter="filter"
|
||||
on-toggle-filter="toggleFilter"
|
||||
on-pin-filter="pinFilter"
|
||||
on-invert-filter="invertFilter"
|
||||
on-delete-filter="deleteFilter"
|
||||
on-edit-filter="editFilter"
|
||||
></filter-pill>
|
||||
|
||||
<div
|
||||
class="filter-link"
|
||||
|
|
|
@ -2,6 +2,7 @@ import _ from 'lodash';
|
|||
import template from 'ui/filter_bar/filter_bar.html';
|
||||
import 'ui/directives/json_input';
|
||||
import '../filter_editor';
|
||||
import './filter_pill/filter_pill';
|
||||
import { filterAppliedAndUnwrap } from 'ui/filter_bar/lib/filter_applied_and_unwrap';
|
||||
import { FilterBarLibMapAndFlattenFiltersProvider } from 'ui/filter_bar/lib/map_and_flatten_filters';
|
||||
import { FilterBarLibMapFlattenAndWrapFiltersProvider } from 'ui/filter_bar/lib/map_flatten_and_wrap_filters';
|
||||
|
|
|
@ -94,20 +94,7 @@ filter-bar {
|
|||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
|
||||
|
||||
&:hover {
|
||||
> .filter-actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> .filter-description {
|
||||
opacity: 0.15;
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
> .filter-actions {
|
||||
.filter-actions {
|
||||
font-size: 1.1em;
|
||||
line-height: 1.4em;
|
||||
position: absolute;
|
||||
|
@ -115,14 +102,17 @@ filter-bar {
|
|||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: none;
|
||||
opacity: 0;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
.action {
|
||||
border: none;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.4);
|
||||
padding-right: 0;
|
||||
margin-right: 5px;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
flex: 1 1 auto;
|
||||
|
||||
&:last-child {
|
||||
border-right: 0;
|
||||
|
@ -136,6 +126,16 @@ filter-bar {
|
|||
}
|
||||
}
|
||||
|
||||
.filter-actions-activated {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.filter-description-deactivated {
|
||||
opacity: 0.15;
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&.negate {
|
||||
background-color: @filter-bar-bar-filter-negate-bg;
|
||||
}
|
||||
|
|
74
src/ui/public/filter_bar/filter_pill/filter_pill.html
Normal file
74
src/ui/public/filter_bar/filter_pill/filter_pill.html
Normal file
|
@ -0,0 +1,74 @@
|
|||
<div
|
||||
class="filter"
|
||||
ng-class="{ negate: pill.filter.meta.negate, disabled: pill.filter.meta.disabled }"
|
||||
data-test-subj="filter filter-{{ pill.filter.meta.disabled ? 'disabled' : 'enabled' }} {{ pill.filter.meta.key ? 'filter-key-' + pill.filter.meta.key : '' }} {{ pill.filter.meta.value ? 'filter-value-' + pill.filter.meta.value : '' }}"
|
||||
ng-mouseover="pill.activateActions()"
|
||||
ng-mouseleave="pill.deactivateActions()"
|
||||
>
|
||||
|
||||
<div class="filter-description" ng-class="{'filter-description-deactivated': pill.areActionsActivated}">
|
||||
<span ng-if="pill.filter.$state.store == 'globalState'"><i class="fa fa-fw fa-thumb-tack pinned"></i></span>
|
||||
<span ng-if="pill.filter.meta.alias">{{ pill.filter.meta.alias }}</span>
|
||||
<span ng-if="!pill.filter.meta.alias">{{ pill.filter.meta.key }}:</span>
|
||||
<span ng-if="!pill.filter.meta.alias">"{{ pill.filter.meta.value }}"</span>
|
||||
</div>
|
||||
|
||||
<div class="filter-actions" ng-class="{'filter-actions-activated': pill.areActionsActivated}">
|
||||
<button
|
||||
class="action filter-toggle"
|
||||
ng-click="pill.onToggleFilter(pill.filter)"
|
||||
data-test-subj="disableFilter-{{ pill.filter.meta.key }}"
|
||||
ng-focus="pill.activateActions()"
|
||||
ng-blur="pill.deactivateActions()"
|
||||
aria-label="{{pill.filter.meta.disabled ? 'Enable filter' : 'Disable filter'}}"
|
||||
>
|
||||
<i ng-show="pill.filter.meta.disabled" class="fa fa-fw fa-square-o disabled"></i>
|
||||
<i ng-hide="pill.filter.meta.disabled" class="fa fa-fw fa-check-square-o enabled"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="action filter-pin"
|
||||
ng-click="pill.onPinFilter(pill.filter)"
|
||||
data-test-subj="pinFilter-{{ pill.filter.meta.key }}"
|
||||
ng-focus="pill.activateActions()"
|
||||
ng-blur="pill.deactivateActions()"
|
||||
aria-label="{{pill.filter.$state.store == 'globalState' ? 'Unpin filter' : 'Pin filter'}}"
|
||||
>
|
||||
<i ng-show="pill.filter.$state.store == 'globalState'" class="fa fa-fw fa-thumb-tack pinned"></i>
|
||||
<i ng-hide="pill.filter.$state.store == 'globalState'" class="fa fa-fw fa-thumb-tack fa-rotate-270 unpinned"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="action filter-invert"
|
||||
ng-click="pill.onInvertFilter(pill.filter)"
|
||||
data-test-subj="invertFilter-{{ pill.filter.meta.key }}"
|
||||
ng-focus="pill.activateActions()"
|
||||
ng-blur="pill.deactivateActions()"
|
||||
aria-label="Invert filter"
|
||||
>
|
||||
<i ng-show="pill.filter.meta.negate" class="fa fa-fw fa-search-plus negative"></i>
|
||||
<i ng-hide="pill.filter.meta.negate" class="fa fa-fw fa-search-minus positive"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="action filter-remove"
|
||||
ng-click="pill.onDeleteFilter(pill.filter)"
|
||||
ng-focus="pill.activateActions()"
|
||||
ng-blur="pill.deactivateActions()"
|
||||
aria-label="Remove filter"
|
||||
>
|
||||
<i class="fa fa-fw fa-trash" data-test-subj="removeFilter-{{ pill.filter.meta.key }}"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="action filter-edit"
|
||||
ng-click="pill.onEditFilter(pill.filter)"
|
||||
ng-focus="pill.activateActions()"
|
||||
ng-blur="pill.deactivateActions()"
|
||||
aria-label="Edit filter"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
33
src/ui/public/filter_bar/filter_pill/filter_pill.js
Normal file
33
src/ui/public/filter_bar/filter_pill/filter_pill.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import template from './filter_pill.html';
|
||||
import { uiModules } from 'ui/modules';
|
||||
|
||||
const module = uiModules.get('kibana');
|
||||
|
||||
module.directive('filterPill', function () {
|
||||
return {
|
||||
template,
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
filter: '=',
|
||||
onToggleFilter: '=',
|
||||
onPinFilter: '=',
|
||||
onInvertFilter: '=',
|
||||
onDeleteFilter: '=',
|
||||
onEditFilter: '=',
|
||||
},
|
||||
bindToController: true,
|
||||
controllerAs: 'pill',
|
||||
controller: function filterPillController() {
|
||||
|
||||
this.activateActions = () => {
|
||||
this.areActionsActivated = true;
|
||||
};
|
||||
|
||||
this.deactivateActions = () => {
|
||||
this.areActionsActivated = false;
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
@ -429,7 +429,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
}
|
||||
|
||||
async getFilters(timeout = defaultFindTimeout) {
|
||||
return await find.allByCssSelector('.filter-bar > .filter', timeout);
|
||||
return await find.allByCssSelector('.filter-bar .filter', timeout);
|
||||
}
|
||||
|
||||
async getFilterDescriptions(timeout = defaultFindTimeout) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue