Commit 51196908 authored by Roman Aleksandrov's avatar Roman Aleksandrov Committed by Commit Bot

oobe-carousel: Improve UX and A11y of dots navigation.

Make dots clickable and add proper aria-labels and role.
Add aria-label to slides for better spoken feedback.

Bug: 1125620
Change-Id: I6f20d4b1e3293aa89c81d4a6da960b6fd0fb0b6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2396084
Commit-Queue: Roman Aleksandrov <raleksandrov@google.com>
Reviewed-by: default avatarDenis Kuznetsov [CET] <antrim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805876}
parent 1d54b27d
......@@ -440,6 +440,15 @@
<message name="IDS_UPDATE_BATTERY_WARNING_TEXT" desc="Text of battery warning which is shown during update process if battery is running out.">
Looks like your Chromebook will run out of power before the update is complete. Make sure it's charging correctly to avoid interruption.
</message>
<message name="IDS_UPDATE_SLIDE_LABEL" desc="Text of slide label for accessibility.">
Extra content <ph name="CURRENT_ELEMENT">$1<ex>1</ex></ph> out of <ph name="TOTAL_ELEMENTS">$2<ex>2</ex></ph>
</message>
<message name="IDS_UPDATE_SELECTED_BUTTON_LABEL" desc="Text of carousel selected button label for accessibility.">
Selected, extra content <ph name="CURRENT_ELEMENT">$1<ex>1</ex></ph> out of <ph name="TOTAL_ELEMENTS">$2<ex>2</ex></ph>
</message>
<message name="IDS_UPDATE_UNSELECTED_BUTTON_LABEL" desc="Text of carousel unselected button label for accessibility.">
Navigate to extra content <ph name="CURRENT_ELEMENT">$1<ex>1</ex></ph> out of <ph name="TOTAL_ELEMENTS">$2<ex>2</ex></ph>
</message>
<message name="IDS_UPDATE_COMPLETED" desc="Notification for update completed">
System update complete. Please restart the system.
</message>
......
ca0462d1b3535a4b491f9f4d6fb0e6761b746100
\ No newline at end of file
ca0462d1b3535a4b491f9f4d6fb0e6761b746100
\ No newline at end of file
81045c3fee552927e2d0a050f0e216158e9a6b31
\ No newline at end of file
......@@ -95,9 +95,9 @@
.slider-dot {
background: var(--google-grey-200);
border-radius: 5px;
cursor: pointer;
height: 10px;
margin: 5px;
pointer-events: none;
transition: background 200ms;
transition-delay: 100ms;
width: 10px;
......@@ -105,6 +105,10 @@
.slider-dot[active] {
background: var(--google-blue-600);
}
.slider-dot:focus {
box-shadow: 0 0 7px 1px rgba(var(--google-blue-600-rgb), .75);
outline: none;
}
.arrow-button {
--cr-icon-button-fill-color: var(--google-grey-400);
......@@ -117,10 +121,13 @@
<div id="navigationContainer">
<cr-icon-button id="left" class="buttons" iron-icon="cr:chevron-left"
class="arrow-button" on-click="movePrev"></cr-icon-button>
<div id="dotsContainer">
<div id="dotsContainer" role="radiogroup">
<template is="dom-repeat" items="[[dots]]">
<span class="slider-dot" aria-hidden="true"
tabindex="-1" active$="[[isActive_(index, slideIndex)]]"></span>
<span class="slider-dot" tabindex="0" on-keypress="onKeypress_"
on-click="onClick_" active$="[[isActive_(index, slideIndex)]]"
aria-label="[[getDotLabel_(index, slideIndex)]]" aria-live="off"
aria-checked="[[isActive_(index, slideIndex)]]"
role="radio"></span>
</template>
</div>
<cr-icon-button id="right" class="buttons" iron-icon="cr:chevron-right"
......
......@@ -35,6 +35,21 @@ Polymer({
value: 10,
observer: 'restartAutoTransition_',
},
/**
* Slide aria-label.
*/
slideLabel: String,
/**
* Selected button aria-label.
*/
selectedButtonLabel: String,
/**
* Unselected button aria-label.
*/
unselectedButtonLabel: String,
},
/**
......@@ -70,25 +85,37 @@ Polymer({
attached() {
this.removeAnimateToHandler = this.removeAnimateTo_.bind(this);
this.removeAnimateFromHandler = this.removeAnimateFrom_.bind(this);
this.countSlides_();
this.prepareCarousel_();
this.restartAutoTransition_();
this.hideNonActiveSlides_();
},
/**
* @private
* Count slides and create dots.
* Count slides and create dots. Set a11y label on slides.
*/
countSlides_() {
prepareCarousel_() {
this.slides = this.$.slot.assignedElements();
this.totalSlides = this.slides.length;
let array = [];
for (let i = 0; i < this.totalSlides; ++i) {
this.slides[i].setAttribute('aria-label', this.getSlideLabel_(i));
this.slides[i].setAttribute('role', 'group');
array.push(i);
}
this.dots = array;
},
/**
* @private
* @param {number} index Index of slide.
* Returns string label for slide.
*/
getSlideLabel_(index) {
return loadTimeData.getStringF(
this.slideLabel, index + 1, this.totalSlides);
},
/**
* @private
*/
......@@ -171,7 +198,6 @@ Polymer({
}
},
/**
* @private
* @param {EventTarget|null} slide
......@@ -276,6 +302,26 @@ Polymer({
'transitionend', this.removeAnimateFromHandler);
},
/**
* @private
* @param {Event} e keypress event.
* On key press function.
*/
onKeypress_(e) {
// Space (32) and enter (13) key codes.
if (e.keyCode == 32 || e.keyCode == 13)
this.slideIndex = e.model.item;
},
/**
* @private
* @param {Event} e click event.
* On dot click function.
*/
onClick_(e) {
this.slideIndex = e.model.item;
},
/**
* @private
* @param {number} index Index of dot.
......@@ -285,6 +331,20 @@ Polymer({
return index == this.slideIndex;
},
/**
* @private
* @param {number} index Index of slide.
* Returns string label for dot.
*/
getDotLabel_(index) {
if (index == this.slideIndex) {
return loadTimeData.getStringF(
this.selectedButtonLabel, index + 1, this.totalSlides);
}
return loadTimeData.getStringF(
this.unselectedButtonLabel, index + 1, this.totalSlides);
},
/**
* @private
* @param {number} toIndex Index of slide which should be shown.
......
......@@ -97,7 +97,10 @@
<div hidden="[[showLowBatteryWarning]]" id="carousel" class="slide-view"
slot="footer">
<oobe-carousel slide-duration-in-seconds=3
auto-transition="[[getAutoTransition_(uiState, autoTransition)]]">
auto-transition="[[getAutoTransition_(uiState, autoTransition)]]"
slide-label="slideLabel"
selected-button-label="slideSelectedButtonLabel"
unselected-button-label="slideUnselectedButtonLabel">
<oobe-slide slot="slides">
<img slot="slide-img"
class="update-illustration oobe-illustration"
......
......@@ -151,6 +151,11 @@ void UpdateScreenHandler::DeclareLocalizedValues(
builder->Add("batteryWarningTitle", IDS_UPDATE_BATTERY_WARNING_TITLE);
builder->Add("batteryWarningText", IDS_UPDATE_BATTERY_WARNING_TEXT);
builder->Add("slideLabel", IDS_UPDATE_SLIDE_LABEL);
builder->Add("slideSelectedButtonLabel", IDS_UPDATE_SELECTED_BUTTON_LABEL);
builder->Add("slideUnselectedButtonLabel",
IDS_UPDATE_UNSELECTED_BUTTON_LABEL);
#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
builder->Add("cancelUpdateHint", IDS_UPDATE_CANCEL);
builder->Add("cancelledUpdateMessage", IDS_UPDATE_CANCELLED);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment