Improve accessibility of the visualize editor (#13780)

* Use aria-expanded and better labels for agg collapsables

* Fix all agg options collapsables, fix #12892

* Label all vis editor inputs correctly, fix #11859

* Fix broken functional test
This commit is contained in:
Tim Roes 2017-08-31 11:46:02 +02:00 committed by Tim Roes
parent 10b9a6b1c7
commit b296d869dd
27 changed files with 140 additions and 47 deletions

View file

@ -78,6 +78,10 @@
<div>
<div class="kuiSideBarCollapsibleTitle">
<div
kbn-accessible-click
aria-expanded="{{!!showColorRange}}"
aria-controls="gaugeOptionsRanges"
aria-label="Toggle range options"
class="kuiSideBarCollapsibleTitle__label"
ng-click="showColorRange = !showColorRange"
>
@ -92,7 +96,7 @@
</div>
</div>
<div ng-show="showColorRange" class="kuiSideBarCollapsibleSection">
<div id="gaugeOptionsRanges" ng-show="showColorRange" class="kuiSideBarCollapsibleSection">
<div class="kuiSideBarSection">
<table class="vis-editor-agg-editor-ranges form-group" ng-show="vis.params.gauge.colorsRange.length">
<tr>
@ -158,6 +162,10 @@
<div ng-show="vis.params.gauge.colorsRange.length > 1">
<div class="kuiSideBarCollapsibleTitle">
<div
kbn-accessible-click
aria-expanded="{{!!showColorOptions}}"
aria-controls="gaugeOptionsColors"
aria-label="Toggle color options"
class="kuiSideBarCollapsibleTitle__label"
ng-click="showColorOptions = !showColorOptions"
>
@ -174,7 +182,7 @@
</span>
</div>
</div>
<div ng-if="showColorOptions" class="kuiSideBarCollapsibleSection">
<div id="gaugeOptionsColors" ng-if="showColorOptions" class="kuiSideBarCollapsibleSection">
<div class="kuiSideBarSection">
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="colorSchema">
@ -203,13 +211,13 @@
</div>
</div>
<div>
<div class="kuiSideBarCollapsibleTitle">
<div
kbn-accessible-click
aria-expanded="{{!!showStyle}}"
aria-controls="gaugeOptionsStyle"
aria-label="Toggle style options"
class="kuiSideBarCollapsibleTitle__label"
ng-click="showStyle = !showStyle"
>
@ -226,7 +234,7 @@
</span>
</div>
</div>
<div ng-if="showStyle" class="kuiSideBarCollapsibleSection">
<div id="gaugeOptionsStyle" ng-if="showStyle" class="kuiSideBarCollapsibleSection">
<div class="kuiSideBarSection">
<div ng-hide="vis.params.gauge.type === 'simple'">

View file

@ -84,6 +84,9 @@
class="kuiSideBarCollapsibleTitle__label"
ng-click="toggleColorRangeSection()"
kbn-accessible-click
aria-expanded="{{!!showColorRange}}"
aria-controls="heatmapOptionsRanges"
aria-label="Toggle custom ranges options"
>
<span
aria-hidden="true"
@ -104,7 +107,12 @@
>
</div>
<div ng-if="vis.params.setColorRange" ng-show="showColorRange" class="kuiSideBarCollapsibleSection">
<div
id="heatmapOptionsRanges"
ng-if="vis.params.setColorRange"
ng-show="showColorRange"
class="kuiSideBarCollapsibleSection"
>
<div class="kuiSideBarSection">
<table class="vis-editor-agg-editor-ranges form-group" ng-show="vis.params.colorsRange.length">
<tr>
@ -172,6 +180,8 @@
class="kuiSideBarCollapsibleTitle__label"
ng-click="toggleLabelSection()"
kbn-accessible-click
aria-expanded="{{!!showLabels}}"
aria-controls="heatmapOptionsLabels"
>
<span
aria-hidden="true"
@ -192,7 +202,12 @@
class="kuiSideBarSectionTitle__action"
>
</div>
<div ng-if="vis.params.valueAxes[0].labels.show" ng-show="showLabels" class="kuiSideBarCollapsibleSection">
<div
id="heatmapOptionsLabels"
ng-if="vis.params.valueAxes[0].labels.show"
ng-show="showLabels"
class="kuiSideBarCollapsibleSection"
>
<div class="kuiSideBarSection">
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="rotateLabels">

View file

@ -4,6 +4,9 @@
class="kuiSideBarCollapsibleTitle__label"
ng-click="isGridOpen = !isGridOpen"
kbn-accessible-click
aria-expanded="{{!!isGridOpen}}"
aria-controls="visGridOptions"
aria-label="Toggle grid options"
>
<span
aria-hidden="true"
@ -16,7 +19,7 @@
</div>
</div>
<div ng-show="isGridOpen" class="kuiSideBarCollapsibleSection">
<div id="visGridOptions" ng-show="isGridOpen" class="kuiSideBarCollapsibleSection">
<!-- General -->
<div class="kuiSideBarSection">
<div class="kuiSideBarFormRow">

View file

@ -15,6 +15,9 @@
class="kuiSideBarCollapsibleTitle__label"
ng-click="isSeriesOpen = !isSeriesOpen"
kbn-accessible-click
aria-expanded="{{!!isSeriesOpen}}"
aria-controls="visSeriesOptions{{$index}}"
aria-label="Toggle {{chart.data.label}} options"
>
<span
aria-hidden="true"
@ -27,7 +30,7 @@
</div>
</div>
<div ng-show="isSeriesOpen" class="kuiSideBarCollapsibleSection">
<div id="visSeriesOptions{{$index}}" ng-show="isSeriesOpen" class="kuiSideBarCollapsibleSection">
<!-- General -->
<div class="kuiSideBarSection">

View file

@ -24,6 +24,9 @@
class="kuiSideBarCollapsibleTitle__label"
ng-click="isValueAxisOpen = !isValueAxisOpen"
kbn-accessible-click
aria-expanded="{{!!isValueAxisOpen}}"
aria-controls="axisOptions{{axis.id}}"
aria-label="Toggle {{axis.name}} options"
>
<span
aria-hidden="true"
@ -48,7 +51,7 @@
></button>
</div>
<div ng-show="isValueAxisOpen" class="kuiSideBarCollapsibleSection">
<div id="axisOptions{{axis.id}}" ng-show="isValueAxisOpen" class="kuiSideBarCollapsibleSection">
<!-- General -->
<div class="kuiSideBarSection">
<div class="kuiSideBarFormRow">

View file

@ -2,10 +2,10 @@
<table class="vis-editor-agg-editor-ranges form-group" ng-show="agg.params.ranges.length">
<tr>
<th>
<label>From</label>
<label id="visEditorDateRangeFrom{{agg.id}}">From</label>
</th>
<th colspan="2">
<label>To</label>
<label id="visEditorDateRangeTo{{agg.id}}">To</label>
</th>
</tr>
@ -13,6 +13,7 @@
ng-repeat="range in agg.params.ranges track by $index">
<td class="kbn-timepicker">
<input
aria-labelledby="visEditorDateRangeFrom{{agg.id}}"
ng-model="range.from"
validate-date-math
type="text"
@ -21,6 +22,7 @@
</td>
<td class="kbn-timepicker">
<input
aria-labelledby="visEditorDateRangeTo{{agg.id}}"
ng-model="range.to"
validate-date-math
class="form-control"
@ -29,6 +31,7 @@
<td>
<button
type="button"
aria-label="Remove this range"
ng-click="agg.params.ranges.splice($index, 1)"
class="kuiButton kuiButton--danger kuiButton--small">
<i class="fa fa-times" ></i>

View file

@ -1,24 +1,38 @@
<div ng-if="aggParam.shouldShow(agg)">
<div>
<label>Extended Bounds</label>
<label id="extendedBoundsLabel{{agg.id}}">Extended Bounds</label>
<kbn-info info="Min and Max do not filter the results, but rather extend the bounds of the result set."></kbn-info>
</div>
<div class="vis-editor-agg-form-row">
<div class="form-group">
<div>Min <small>(optional)</small></div>
<label
id="extendedBoundsMinLabel{{agg.id}}"
for="extendedBoundsMinInput{{agg.id}}"
>
Min <small>(optional)</small>
</label>
<input
id="extendedBoundsMinInput{{agg.id}}"
aria-labelledby="extendedBoundsLabel{{agg.id}} extendedBoundsMinLabel{{agg.id}}"
ng-model="agg.params.extended_bounds.min"
type="number"
class="form-control"
name="extended_bounds.min" />
</div>
<div class="form-group">
<div>Max <small>(optional)</small></div>
<label
id="extendedBoundsMaxLabel{{agg.id}}"
for="extendedBoundsMaxInput{{agg.id}}"
>
Max <small>(optional)</small>
</label>
<input
id="extendedBoundsMaxInput{{agg.id}}"
aria-labelledby="extendedBoundsLabel{{agg.id}} extendedBoundsMaxLabel{{agg.id}}"
ng-model="agg.params.extended_bounds.max"
type="number"
class="form-control"
name="extended_bounds.max" />
</div>
</div>
</div>
</div>

View file

@ -1,9 +1,10 @@
<div class="form-group">
<label for="field">
<label>
Field
</label>
<ui-select
title="Aggregation Field"
name="field"
required
class="vis-editor-field-ui-select field-select"

View file

@ -1,7 +1,7 @@
<div class="form-group">
<div ng-repeat="filter in agg.params.filters">
<div class="vis-editor-agg-header">
<label>
<label for="visEditorFilterInput{{agg.id}}">
Filter {{$index + 1}}
<span ng-if="filter.label">- {{ filter.label }}</span>
</label>
@ -10,11 +10,15 @@
<button
ng-click="showConfig = !showConfig"
type="button"
aria-label="Toggle filter label"
aria-expanded="{{!!showConfig}}"
aria-controls="visEditorFilterLabel{{agg.id}}"
class="kuiButton kuiButton--basic kuiButton--small">
<i class="fa fa-tag"></i>
</button>
<button
type="button"
aria-label="Remove this filter"
ng-click="agg.params.filters.splice($index, 1)"
class="kuiButton kuiButton--danger kuiButton--small">
<i class="fa fa-times"></i>
@ -24,6 +28,7 @@
<div class="form-group">
<input
id="visEditorFilterInput{{agg.id}}"
parse-query
ng-model="filter.input.query"
type="text"
@ -31,9 +36,10 @@
name="filter{{$index}}">
</div>
<div class="form-group" ng-show="showConfig">
<label>Filter {{$index + 1}} label</label>
<div class="form-group" ng-show="showConfig" id="visEditorFilterLabel{{agg.id}}">
<label for="visEditorFilterLabelInput{{agg.id}}">Filter {{$index + 1}} label</label>
<input
id="visEditorFilterLabelInput{{agg.id}}"
ng-model="filter.label"
placeholder="Label"
type="text"

View file

@ -1,5 +1,5 @@
<div class="form-group">
<label>
<label for="visEditorInterval{{agg.id}}">
Interval
<kbn-info
ng-show="agg.buckets.getInterval().scaled"
@ -9,6 +9,7 @@
</kbn-info>
</label>
<select
id="visEditorInterval{{agg.id}}"
ng-if="aggParam.options"
ng-model="agg.params.interval"
ng-change="agg.write()"
@ -19,6 +20,7 @@
<option value="">-- select a valid interval --</option>
</select>
<input
aria-label="Custom interval"
type="text"
name="customInterval"
ng-model="agg.params.customInterval"
@ -28,6 +30,7 @@
class="form-control"
required />
<input
id="visEditorInterval{{agg.id}}"
ng-if="!aggParam.options"
ng-model="agg.params.interval"
required

View file

@ -8,10 +8,10 @@
<table class="vis-editor-agg-editor-ranges form-group" ng-show="agg.params.ranges.fromTo.length">
<tr>
<th>
<label>From</label>
<label id="visEditorIpRangeFromLabel{{agg.id}}">From</label>
</th>
<th colspan="2">
<label>To</label>
<label id="visEditorIpRangeToLabel{{agg.id}}">To</label>
</th>
</tr>
@ -19,6 +19,7 @@
ng-repeat="range in agg.params.ranges.fromTo track by $index">
<td>
<input
aria-labelledby="visEditorIpRangeFromLabel{{agg.id}}"
validate-ip
ng-model="range.from"
type="text"
@ -27,6 +28,7 @@
</td>
<td>
<input
aria-labelledby="visEditorIpRangeToLabel{{agg.id}}"
validate-ip
ng-model="range.to"
class="form-control"
@ -35,6 +37,7 @@
<td>
<button
type="button"
aria-label="Remove this range"
ng-click="agg.params.ranges.fromTo.splice($index, 1)"
class="kuiButton kuiButton--danger kuiButton--small">
<i class="fa fa-times" ></i>
@ -63,7 +66,7 @@
<table class="vis-editor-agg-editor-ranges form-group" ng-show="agg.params.ranges.mask.length">
<tr>
<th>
<label>Mask</label>
<label id="visEditorIpRangeCidrLabel{{agg.id}}">CIDR Mask</label>
</th>
</tr>
@ -71,6 +74,7 @@
ng-repeat="range in agg.params.ranges.mask track by $index">
<td>
<input
aria-labelledby="visEditorIpRangeCidrLabel{{agg.id}}"
validate-cidr-mask
ng-model="range.mask"
type="text"
@ -80,6 +84,7 @@
<td>
<button
type="button"
aria-label="Remove this CIDR mask"
ng-click="agg.params.ranges.mask.splice($index, 1)"
class="kuiButton kuiButton--danger kuiButton--small">
<i class="fa fa-times" ></i>

View file

@ -1,7 +1,8 @@
<div ng-controller="aggParam.controller">
<div class="form-group">
<label>Order By</label>
<label for="visEditorOrder{{agg.id}}">Order By</label>
<select
id="visEditorOrder{{agg.id}}"
name="orderBy"
ng-model="agg.params.orderBy"
required

View file

@ -1,7 +1,8 @@
<div class="vis-editor-agg-form-row">
<div ng-if="agg.type.params.byName.order" class="form-group">
<label>Order</label>
<label for="visEditorOrderByOrder{{agg.id}}">Order</label>
<select
id="visEditorOrderByOrder{{agg.id}}"
name="order"
ng-model="agg.params.order"
required
@ -10,8 +11,9 @@
</select>
</div>
<div class="form-group">
<label>Size</label>
<label for="visEditorOrderBySize{{agg.id}}">Size</label>
<input
id="visEditorOrderBySize{{agg.id}}"
name="size"
ng-model="agg.params.size"
required

View file

@ -1,9 +1,10 @@
<div class="form-group">
<label>Values</label>
<label id="visEditorPercentileRanksLabel{{agg.id}}">Values</label>
<kbn-number-list
ng-model="agg.params.values"
unit-name="value"
range="[-Infinity,Infinity]"
labelledby-id="visEditorPercentileRanksLabel{{agg.id}}"
>
</kbn-number-list>
</div>

View file

@ -1,10 +1,11 @@
<div class="form-group">
<label>Percents</label>
<label id="visEditorPercentileLabel{{agg.id}}">Percents</label>
<kbn-number-list
ng-model="agg.params.percents"
unit-name="percent"
range="[0,100]"
validate-ascending-order="false"
labelledby-id="visEditorPercentileLabel{{agg.id}}"
>
</kbn-number-list>
</div>

View file

@ -1,8 +1,9 @@
<div class="vis-editor-agg-form-row" ng-controller="agg.type.params.byName.precision.controller">
<div ng-if="!agg.params.autoPrecision" class="form-group">
<label>Precision</label>
<label for="visEditorMapPrecision{{agg.id}}">Precision</label>
<div class="vis-editor-agg-form-row">
<input
id="visEditorMapPrecision{{agg.id}}"
name="precision"
ng-model="agg.params.precision"
required

View file

@ -1,10 +1,10 @@
<table class="vis-editor-agg-editor-ranges form-group" ng-show="agg.params.ranges.length">
<tr>
<th>
<label>From</label>
<label id="visEditorRangeFrom{{agg.id}}">From</label>
</th>
<th colspan="2">
<label>To</label>
<label id="visEditorRangeTo{{agg.id}}">To</label>
</th>
</tr>
@ -12,6 +12,7 @@
ng-repeat="range in agg.params.ranges track by $index">
<td>
<input
aria-labelledby="visEditorRangeFrom{{agg.id}}"
ng-model="range.from"
type="number"
class="form-control"
@ -20,6 +21,7 @@
</td>
<td>
<input
aria-labelledby="visEditorRangeTo{{agg.id}}"
ng-model="range.to"
type="number"
class="form-control"
@ -29,6 +31,7 @@
<td>
<button
type="button"
aria-label="Remove this range"
ng-click="agg.params.ranges.splice($index, 1)"
class="kuiButton kuiButton--danger kuiButton--small">
<i class="fa fa-times"></i>

View file

@ -1,6 +1,6 @@
<div class="form-group regex">
<span class="hintbox-label" ng-click="showJsonHint = !showJsonHint">
<label>JSON Input</label>
<label for="visEditorRawJson{{agg.id}}">JSON Input</label>
<i class="fa fa-info-circle"></i>
</span>
<div class="hintbox" ng-show="showJsonHint">
@ -11,6 +11,7 @@
<p>
<textarea
type="text"
aria-labelledby="visEditorRawJson{{agg.id}}"
class="form-control"
ng-model="agg.params.json"
validate-json

View file

@ -1,7 +1,8 @@
<div ng-if="!aggParam.disabled(agg)">
<div class="form-group regex">
<label>{{ aggParam.name | label }} Pattern</label>
<label for="visEditorRegexInput{{agg.id}}{{aggParam.name}}">{{ aggParam.name | label }} Pattern</label>
<input
id="visEditorRegexInput{{agg.id}}{{aggParam.name}}"
type="text"
class="form-control"
ng-model="agg.params[aggParam.name].pattern"

View file

@ -1,6 +1,11 @@
<div class="form-group">
<label>{{ aggParam.name | label }}</label>
<label for="visEditorStringInput{{agg.id}}{{aggParam.name}}">{{ aggParam.name | label }}</label>
<div>
<input type="text" ng-model="agg.params[aggParam.name]" class="form-control">
<input
type="text"
id="visEditorStringInput{{agg.id}}{{aggParam.name}}"
ng-model="agg.params[aggParam.name]"
class="form-control"
>
</div>
</div>
</div>

View file

@ -1,7 +1,8 @@
<div ng-controller="aggParam.controller">
<div class="form-group">
<label>Metric</label>
<label for="visEditorSubAggMetric{{agg.id}}">Metric</label>
<select
id="visEditorSubAggMetric{{agg.id}}"
name="metricAgg"
ng-model="agg.params.metricAgg"
agg="agg"

View file

@ -1,6 +1,6 @@
<div ng-controller="aggParam.controller" class="vis-editor-agg-form-row">
<div class="form-group">
<label>
<label for="visEditorTopHitsAggregate{{agg.id}}">
Aggregate With
<kbn-info
info="Choose a strategy for combining multiple hits or a multi-valued field into a single metric."
@ -10,6 +10,7 @@
<select
required
id="visEditorTopHitsAggregate{{agg.id}}"
name="aggregate"
ng-model="agg.params.aggregate"
ng-options="opt as opt.display for opt in options| orderBy: 'display' track by opt.val"
@ -17,7 +18,7 @@
></select>
</div>
<div class="form-group">
<label>
<label for="visEditorTopHitsSize{{agg.id}}">
Size
<kbn-info
info="Request top-K hits. Multiple hits will be combined via 'aggregate with'."
@ -27,6 +28,7 @@
<input
required
id="visEditorTopHitsSize{{agg.id}}"
name="size"
ng-model="agg.params.size"
class="form-control"

View file

@ -1,11 +1,12 @@
<div class="form-group">
<label for="sort">
<label>
Sort On
</label>
<ui-select
name="field"
sortField
title="Sort on"
class="vis-editor-field-ui-select"
ng-show="sortFieldOptions.length"
ng-model="agg.params.sortField"
@ -26,11 +27,12 @@
</div>
<div class="form-group">
<label>
<label for="visEditorTopSort{{agg.id}}">
Order
</label>
<select
id="visEditorTopSort{{agg.id}}"
name="sortOrder"
ng-model="agg.params.sortOrder"
required

View file

@ -7,12 +7,14 @@
ng-model="numberListCntr.getList()[$index]"
kbn-number-list-input
input-focus
aria-labelledby="{{numberListCntr.labelledbyId}}"
class="form-control"
>
</div>
<div class="kuiFieldGroupSection">
<button
aria-label="Remove this rank value"
ng-click="numberListCntr.remove($index, 1)"
class="kuiButton kuiButton--danger kuiButton--small"
type="button"

View file

@ -14,10 +14,13 @@ uiModules
require: 'ngModel',
scope: {
validateAscendingOrder: '=?',
labelledbyId: '@',
},
controller: function ($scope, $attrs, $parse) {
const self = this;
self.labelledbyId = $scope.labelledbyId;
// Called from the pre-link function once we have the controllers
self.init = function (modelCntr) {
self.modelCntr = modelCntr;
@ -109,4 +112,3 @@ uiModules
},
};
});

View file

@ -3,9 +3,12 @@
<!-- open/close editor -->
<button
aria-label="{{ editorOpen ? 'Close Editor' : 'Open Editor' }}"
aria-label="Toggle {{agg.schema.title}} editor"
ng-click="editorOpen = !editorOpen"
aria-expanded="{{ !!editorOpen }}"
aria-controls="visAggEditorParams{{agg.id}}"
type="button"
data-test-subj="toggleEditor"
class="kuiButton kuiButton--primary kuiButton--small vis-editor-agg-header-toggle">
<i aria-hidden="true" ng-class="{ 'fa-caret-down': editorOpen, 'fa-caret-right': !editorOpen }" class="fa"></i>
</button>
@ -81,6 +84,7 @@
</div>
<vis-editor-agg-params
id="visAggEditorParams{{agg.id}}"
agg="agg"
group-name="groupName"
ng-show="editorOpen"

View file

@ -193,7 +193,7 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
}
async clickMetricEditor() {
await find.clickByCssSelector('button[aria-label="Open Editor"]');
await find.clickByCssSelector('button[data-test-subj="toggleEditor"]');
}
async clickNewSearch() {