commit c5be4968fa9ae8d6317ffeecce1bcca29518a9b2
parent 632974cc3a691b9823bbb35641bd5e4e5dcdc163
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date: Thu, 28 Dec 2023 17:05:18 -0800
Improve accessibility
Diffstat:
9 files changed, 50 insertions(+), 39 deletions(-)
diff --git a/src/App.vue b/src/App.vue
@@ -7,7 +7,7 @@ import VueFeather from 'vue-feather';
<header>
<router-link :to="{ name: $route.meta.back }" v-if="$route.meta.back"
class="icon" title="Back">
- <vue-feather type="chevron-left"/>
+ <vue-feather type="chevron-left" aria-hidden="true"/>
</router-link>
<h1 v-if="$route.meta.title">
diff --git a/src/components/TargetEditor.vue b/src/components/TargetEditor.vue
@@ -4,16 +4,17 @@
<tr>
<th>
Edit
- <input v-model="internalValue.name" placeholder="Target set label"/>
- <button class="icon" :title="isCustomSet ? 'Delete Target Set' : 'Revert Target Set'"
+ <input v-model="internalValue.name" placeholder="Target set label"
+ aria-label="Target set label"/>
+ <button class="icon" :title="isCustomSet ? 'Delete target set' : 'Revert target set'"
@click="revert">
- <vue-feather :type="isCustomSet ? 'trash-2' : 'rotate-ccw'"/>
+ <vue-feather :type="isCustomSet ? 'trash-2' : 'rotate-ccw'" aria-hidden="true"/>
</button>
</th>
<th>
<button class="icon" title="Close" @click="close">
- <vue-feather type="x"/>
+ <vue-feather type="x" aria-hidden="true"/>
</button>
</th>
</tr>
@@ -22,9 +23,9 @@
<tbody>
<tr v-for="(item, index) in internalValue.targets" :key="index">
<td v-if="item.result === 'time'">
- <decimal-input v-model="item.distanceValue" aria-label="Distance Value"
+ <decimal-input v-model="item.distanceValue" aria-label="Target distance value"
:min="0" :digits="2"/>
- <select v-model="item.distanceUnit" aria-label="Distance Unit">
+ <select v-model="item.distanceUnit" aria-label="Target distance unit">
<option v-for="(value, key) in distanceUnits" :key="key" :value="key">
{{ value.name }}
</option>
@@ -32,12 +33,12 @@
</td>
<td v-else>
- <time-input v-model="item.time" aria-label="Time"/>
+ <time-input v-model="item.time" label="Target duration"/>
</td>
<td>
- <button class="icon" title="Remove Target" @click="removeTarget(index)">
- <vue-feather type="trash-2"/>
+ <button class="icon" title="Remove target" @click="removeTarget(index)">
+ <vue-feather type="trash-2" aria-hidden="true"/>
</button>
</td>
</tr>
@@ -52,10 +53,10 @@
<tfoot>
<tr>
<td colspan="2">
- <button title="Add Distance Target" @click="addDistanceTarget">
+ <button title="Add distance target" @click="addDistanceTarget">
Add distance target
</button>
- <button v-if="timeTargets" title="Add Time Target" @click="addTimeTarget">
+ <button v-if="timeTargets" title="Add time target" @click="addTimeTarget">
Add time target
</button>
<br/>
diff --git a/src/components/TargetSetSelector.vue b/src/components/TargetSetSelector.vue
@@ -1,19 +1,19 @@
<template>
<span class="target-set-selector">
- <select v-model="internalValue">
+ <select v-model="internalValue" aria-label="Selected target set">
<option v-for="(item, index) in targetSets" :key="index" :value="index">
{{ item.name }}
</option>
<option value="_new">[ Create New Target Set ]</option>
</select>
- <button class="icon" title="Edit Target Set" @click="$refs.dialog.showModal()">
- <vue-feather type="edit"/>
+ <button class="icon" title="Edit target set" @click="$refs.dialog.showModal()">
+ <vue-feather type="edit" aria-hidden="true"/>
</button>
- <dialog ref="dialog" class="target-set-editor-dialog">
+ <dialog ref="dialog" class="target-set-editor-dialog" aria-label="Edit target set">
<target-editor @close="$refs.dialog.close()" v-model="targetSets[internalValue]"
- @revert="revertTargetSet(); $refs.dialog.close()"
+ @revert="revertTargetSet"
:isCustomSet="!internalValue.startsWith('_')"/>
</dialog>
</span>
@@ -128,6 +128,7 @@ export default {
// Remove custom set
delete this.targetSets[this.internalValue];
this.internalValue = [...Object.keys(this.targetSets), '_new'][0];
+ if (this.$refs.dialog.close) this.$refs.dialog.close();
}
},
},
diff --git a/src/components/TimeInput.vue b/src/components/TimeInput.vue
@@ -1,14 +1,14 @@
<template>
<div class="time-input">
- <integer-input class="hours" aria-label="hours" v-if="showHours"
+ <integer-input class="hours" :aria-label="label + ' hours'" v-if="showHours"
:min="0" :max="99" :padding="1" v-model="hours"
:arrow-keys="false" @keydown="onkeydown($event, 3600)"/>
<span v-if="showHours">:</span>
- <integer-input class="minutes" aria-label="minutes"
+ <integer-input class="minutes" :aria-label="label + ' minutes'"
:min="0" :max="59" :padding="2" v-model="minutes"
:arrow-keys="false" @keydown="onkeydown($event, 60)"/>
<span>:</span>
- <decimal-input class="seconds" aria-label="seconds"
+ <decimal-input class="seconds" :aria-label="label + ' seconds'"
:min="0" :max="59.99" :padding="2" :digits="2" v-model="seconds"
:arrow-keys="false" @keydown="onkeydown($event, 1)"/>
</div>
@@ -45,6 +45,14 @@ export default {
type: Boolean,
default: true,
},
+
+ /**
+ * The prefix for each field's aria-label
+ */
+ label: {
+ type: String,
+ default: '',
+ },
},
data() {
diff --git a/src/views/AboutPage.vue b/src/views/AboutPage.vue
@@ -10,10 +10,10 @@
<p>
Running Tools can be installed as a progressive web app so it works offline:
<ul>
- <li>On iOS devices, open Running Tools in Safari, press <vue-feather type="share"/>, and
- select Add to Home Screen</li>
+ <li>On iOS devices, open Running Tools in Safari, press <span aria-label="Share">
+ <vue-feather type="share" aria-hidden="true"/></span>, and select Add to Home Screen</li>
<li>On all other platforms, open Running Tools in Chrome and click Install
- <img src="@/assets/chrome-install.png" height="24" class="chrome-install" alt="Install"/>
+ <img src="@/assets/chrome-install.png" height="24" class="chrome-install" alt=""/>
</li>
</ul>
</p>
diff --git a/src/views/PaceCalculator.vue b/src/views/PaceCalculator.vue
@@ -4,9 +4,9 @@
<div class="input">
<div>
Distance:
- <decimal-input v-model="inputDistance" aria-label="distance value"
+ <decimal-input v-model="inputDistance" aria-label="Input distance value"
:min="0" :digits="2"/>
- <select v-model="inputUnit" aria-label="distance unit">
+ <select v-model="inputUnit" aria-label="Input distance unit">
<option v-for="(value, key) in distanceUnits" :key="key" :value="key">
{{ value.name }}
</option>
@@ -14,7 +14,7 @@
</div>
<div>
Time:
- <time-input v-model="inputTime"/>
+ <time-input v-model="inputTime" label="Input duration"/>
</div>
</div>
diff --git a/src/views/RaceCalculator.vue b/src/views/RaceCalculator.vue
@@ -4,8 +4,8 @@
<div class="input">
<div>
Distance:
- <decimal-input v-model="inputDistance" aria-label="Distance value" :min="0" :digits="2"/>
- <select v-model="inputUnit" aria-label="Distance unit">
+ <decimal-input v-model="inputDistance" aria-label="Input distance value" :min="0" :digits="2"/>
+ <select v-model="inputUnit" aria-label="Input distance unit">
<option v-for="(value, key) in distanceUnits" :key="key" :value="key">
{{ value.name }}
</option>
@@ -13,7 +13,7 @@
</div>
<div>
Time:
- <time-input v-model="inputTime"/>
+ <time-input v-model="inputTime" label="Input race duration"/>
</div>
</div>
@@ -26,7 +26,7 @@
<div class="advanced-options" v-show="showAdvancedOptions">
<div>
Prediction Model:
- <select v-model="model" aria-label="Prediction Model">
+ <select v-model="model" aria-label="Prediction model">
<option value="AverageModel">Average</option>
<option value="PurdyPointsModel">Purdy Points Model</option>
<option value="VO2MaxModel">V̇O₂ Max Model</option>
@@ -36,7 +36,7 @@
</div>
<div>
Riegel Exponent:
- <decimal-input v-model="riegelExponent" aria-label="Riegel Exponent" :min="1" :max="1.3"
+ <decimal-input v-model="riegelExponent" aria-label="Riegel exponent" :min="1" :max="1.3"
:digits="2" :step="0.01"/>
(default: 1.06)
</div>
diff --git a/src/views/SplitCalculator.vue b/src/views/SplitCalculator.vue
@@ -34,7 +34,8 @@
</td>
<td v-if="targetSets[selectedTargetSet]">
- <time-input v-model="targetSets[selectedTargetSet].targets[index].split" :showHours="false"/>
+ <time-input v-model="targetSets[selectedTargetSet].targets[index].split"
+ label="Split duration" :showHours="false"/>
</td>
<td>
diff --git a/src/views/UnitCalculator.vue b/src/views/UnitCalculator.vue
@@ -1,17 +1,17 @@
<template>
<div class="unit-calculator">
- <select class="category" v-model="category">
+ <select class="category" v-model="category" aria-label="Selected unit category">
<option value="distance">Distance</option>
<option value="time">Time</option>
<option value="speed_and_pace">Speed & Pace</option>
</select>
<time-input v-if="getUnitType(inputUnit) === 'time'" class="input-value"
- v-model="inputValue"/>
- <decimal-input v-else class="input-value" aria-label="input value"
+ label="Input time" v-model="inputValue"/>
+ <decimal-input v-else class="input-value" aria-label="Input value"
v-model="inputValue" :min="0" :digits="2"/>
- <select v-model="inputUnit" class="input-units" aria-label="input units">
+ <select v-model="inputUnit" class="input-units" aria-label="Input units">
<option v-for="(value, key) in units" :key="key" :value="key">
{{ value.name }}
</option>
@@ -19,14 +19,14 @@
<span class="equals"> = </span>
- <span v-if="getUnitType(outputUnit) === 'time'" class="output-value">
+ <span v-if="getUnitType(outputUnit) === 'time'" class="output-value" aria-label="Output value">
{{ formatDuration(outputValue, 6, 3, true) }}
</span>
- <span v-else class="output-value">
+ <span v-else class="output-value" aria-label="Output value">
{{ formatNumber(outputValue, 0, 3, true) }}
</span>
- <select v-model="outputUnit" class="output-units" aria-label="output units">
+ <select v-model="outputUnit" class="output-units" aria-label="Output units">
<option v-for="(value, key) in units" :key="key" :value="key">
{{ value.name }}
</option>