Dev Tools console is now keyboard accessible (#13946)
* Remove redundant kbn-accessible-click * Make history in console accessible, fix #13937
This commit is contained in:
parent
199e5c3623
commit
821bd96d32
|
@ -5,7 +5,6 @@
|
|||
<div id="editor_actions">
|
||||
<kbn-tooltip text="click to send request">
|
||||
<button
|
||||
kbn-accessible-click
|
||||
class="editor_action"
|
||||
ng-click="sendSelected()"
|
||||
data-test-subj="send-request-button">
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
<div class="kuiLocalDropdownTitle">History</div>
|
||||
|
||||
<div class="history-body">
|
||||
<ul class="list-group history-reqs">
|
||||
<ul
|
||||
class="list-group history-reqs"
|
||||
tabindex="0"
|
||||
role="listbox"
|
||||
aria-activedescendant="historyReq{{ history.selectedIndex }}"
|
||||
scrollto-activedescendant
|
||||
ng-keydown="history.onKeyDown($event)"
|
||||
aria-label="History of sent requests"
|
||||
>
|
||||
<li
|
||||
role="option"
|
||||
ng-repeat="req in history.reqs"
|
||||
id="historyReq{{$index}}"
|
||||
ng-class="{ selected: history.viewingReq === req }"
|
||||
ng-click="history.selectedReq = req; history.viewingReq = req"
|
||||
ng-click="history.selectedReq = req; history.viewingReq = req; history.selectedIndex = $index"
|
||||
ng-mouseenter="history.viewingReq = req"
|
||||
ng-mouseleave="history.viewingReq = history.selectedReq"
|
||||
ng-dblclick="history.restore(req)"
|
||||
aria-label="{{:: 'Request: ' + history.describeReq(req) }}"
|
||||
aria-selected="{{ history.selectedReq === req }}"
|
||||
class="list-group-item history-req"
|
||||
>
|
||||
{{ history.describeReq(req) }}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { keyCodes } from 'ui_framework/services';
|
||||
|
||||
var { memoize } = require('lodash');
|
||||
let moment = require('moment');
|
||||
|
||||
|
@ -13,7 +15,8 @@ require('ui/modules')
|
|||
controllerAs: 'history',
|
||||
controller: function ($scope, $element) {
|
||||
this.reqs = history.getHistory();
|
||||
this.selectedReq = this.reqs[0];
|
||||
this.selectedIndex = 0;
|
||||
this.selectedReq = this.reqs[this.selectedIndex];
|
||||
this.viewingReq = this.selectedReq;
|
||||
|
||||
// calculate the text description of a request
|
||||
|
@ -40,6 +43,25 @@ require('ui/modules')
|
|||
history.restoreFromHistory(req);
|
||||
$scope.kbnTopNav.close();
|
||||
};
|
||||
|
||||
this.onKeyDown = (ev) => {
|
||||
if (ev.keyCode === keyCodes.ENTER) {
|
||||
this.restore();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev.keyCode === keyCodes.UP) {
|
||||
ev.preventDefault();
|
||||
this.selectedIndex--;
|
||||
} else if (ev.keyCode === keyCodes.DOWN) {
|
||||
ev.preventDefault();
|
||||
this.selectedIndex++;
|
||||
}
|
||||
|
||||
this.selectedIndex = Math.min(Math.max(0, this.selectedIndex), this.reqs.length - 1);
|
||||
this.selectedReq = this.reqs[this.selectedIndex];
|
||||
this.viewingReq = this.reqs[this.selectedIndex];
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import '../scrollto_activedescendant';
|
||||
|
||||
describe('scrolltoActivedescendant directive', () => {
|
||||
let $compile;
|
||||
let $rootScope;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
|
||||
beforeEach(ngMock.inject((_$compile_, _$rootScope_) => {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
}));
|
||||
|
||||
it('should call scrollIntoView on aria-activedescendant changes', () => {
|
||||
const scope = $rootScope.$new();
|
||||
scope.ad = '';
|
||||
const element = $compile(`<div aria-activedescendant="{{ad}}" scrollto-activedescendant>
|
||||
<span id="child1"></span>
|
||||
<span id="child2"></span>
|
||||
</div>`)(scope);
|
||||
const child1 = element.find('#child1');
|
||||
const child2 = element.find('#child2');
|
||||
sinon.spy(child1[0], 'scrollIntoView');
|
||||
sinon.spy(child2[0], 'scrollIntoView');
|
||||
scope.ad = 'child1';
|
||||
scope.$digest();
|
||||
expect(child1[0].scrollIntoView.calledOnce).to.be.eql(true);
|
||||
scope.ad = 'child2';
|
||||
scope.$digest();
|
||||
expect(child2[0].scrollIntoView.calledOnce).to.be.eql(true);
|
||||
});
|
||||
|
||||
});
|
|
@ -1 +1,2 @@
|
|||
import './kbn_accessible_click';
|
||||
import './scrollto_activedescendant';
|
||||
|
|
22
src/ui/public/accessibility/scrollto_activedescendant.js
Normal file
22
src/ui/public/accessibility/scrollto_activedescendant.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* This directive can be applied to an element, that has also aria-activedescendant applied.
|
||||
* It will make sure, that whenever aria-activedescendant changes, the new element
|
||||
* referenced by it, will be scrolled into visible view, by calling its `scrollIntoView`
|
||||
* method.
|
||||
*/
|
||||
|
||||
import { uiModules } from 'ui/modules';
|
||||
|
||||
uiModules.get('kibana')
|
||||
.directive('scrolltoActivedescendant', () => ({
|
||||
link(scope, element, attrs) {
|
||||
scope.$watch(() => attrs.ariaActivedescendant, (val) => {
|
||||
if (val) {
|
||||
const activeDescendant = element.find(`#${val}`);
|
||||
if (activeDescendant.length) {
|
||||
activeDescendant[0].scrollIntoView();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
Loading…
Reference in a new issue