Skip to content

Commit 3cf00f2

Browse files
Merge pull request #2 from vue-a11y/enhance-a11y
Accessibility and Usability Enhancements for the VoiceCapture
2 parents 5afd967 + f9a9f4f commit 3cf00f2

File tree

3 files changed

+111
-62
lines changed

3 files changed

+111
-62
lines changed

Diff for: src/App.vue

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ function returnVoiceTranscript(transcript) {
6262
:status="isVoiceCaptureExample"
6363
:lang="langSelect"
6464
:mode="modeSelect"
65+
:clipboard="true"
6566
@voiceTranscript="returnVoiceTranscript"
6667
@onStatus="statusVoiceCapture"
6768
/>

Diff for: src/components/VoiceCapture.translate.ts

+78-52
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,106 @@
11
export const translates = {
22
en: {
3-
speakNow: 'Speak now',
4-
noSpeech: 'No speech detected.',
5-
audioCapture: 'Audio capture problem.',
6-
enableMicrophone: 'Enable the microphone',
3+
speakNow: "Speak now",
4+
noSpeech: "No speech detected.",
5+
audioCapture: "Audio capture problem.",
6+
enableMicrophone: "Enable the microphone",
7+
close: "Close voice capture",
8+
open: "Start voice capture",
79
},
810
pt: {
9-
speakNow: 'Fale agora',
10-
noSpeech: 'Nenhuma fala detectada.',
11-
audioCapture: 'Problema na captura de áudio.',
12-
enableMicrophone: 'Ative o microfone',
11+
speakNow: "Fale agora",
12+
noSpeech: "Nenhuma fala detectada.",
13+
audioCapture: "Problema na captura de áudio.",
14+
enableMicrophone: "Ative o microfone",
15+
close: "Fechar captura de voz",
16+
open: "Iniciar captura de voz",
1317
},
1418
es: {
15-
speakNow: 'Habla ahora',
16-
noSpeech: 'No se detectó voz.',
17-
audioCapture: 'Problema en la captura de audio.',
18-
enableMicrophone: 'Activa el micrófono',
19+
speakNow: "Habla ahora",
20+
noSpeech: "No se detectó voz.",
21+
audioCapture: "Problema en la captura de audio.",
22+
enableMicrophone: "Activa el micrófono",
23+
close: "Cerrar captura de voz",
24+
open: "Iniciar captura de voz",
1925
},
2026
fr: {
21-
speakNow: 'Parlez maintenant',
22-
noSpeech: 'Aucune parole détectée.',
23-
audioCapture: 'Problème de capture audio.',
24-
enableMicrophone: 'Activez le microphone',
27+
speakNow: "Parlez maintenant",
28+
noSpeech: "Aucune parole détectée.",
29+
audioCapture: "Problème de capture audio.",
30+
enableMicrophone: "Activez le microphone",
31+
close: "Fermer la capture vocale",
32+
open: "Démarrer la capture vocale",
2533
},
2634
de: {
27-
speakNow: 'Sprich jetzt',
28-
noSpeech: 'Keine Sprache erkannt.',
29-
audioCapture: 'Audioproblem.',
30-
enableMicrophone: 'Aktivieren Sie das Mikrofon',
35+
speakNow: "Sprich jetzt",
36+
noSpeech: "Keine Sprache erkannt.",
37+
audioCapture: "Audioproblem.",
38+
enableMicrophone: "Aktivieren Sie das Mikrofon",
39+
close: "Spracherfassung schließen",
40+
open: "Spracherfassung starten",
3141
},
3242
it: {
33-
speakNow: 'Parla ora',
34-
noSpeech: 'Nessuna parola rilevata.',
35-
audioCapture: 'Problema con la cattura audio.',
36-
enableMicrophone: 'Abilita il microfono',
43+
speakNow: "Parla ora",
44+
noSpeech: "Nessuna parola rilevata.",
45+
audioCapture: "Problema con la cattura audio.",
46+
enableMicrophone: "Abilita il microfono",
47+
close: "Chiudere la cattura vocale",
48+
open: "Avviare la cattura vocale",
3749
},
3850
ja: {
39-
speakNow: '今話してください',
40-
noSpeech: '音声が検出されませんでした。',
41-
audioCapture: 'オーディオキャプチャの問題。',
42-
enableMicrophone: 'マイクを有効にしてください',
51+
speakNow: "今話してください",
52+
noSpeech: "音声が検出されませんでした。",
53+
audioCapture: "オーディオキャプチャの問題。",
54+
enableMicrophone: "マイクを有効にしてください",
55+
close: "音声キャプチャを閉じる",
56+
open: "音声キャプチャを開始",
4357
},
4458
zh: {
45-
speakNow: '现在说话',
46-
noSpeech: '没有检测到语音。',
47-
audioCapture: '音频捕获问题。',
48-
enableMicrophone: '启用麦克风',
59+
speakNow: "现在说话",
60+
noSpeech: "没有检测到语音。",
61+
audioCapture: "音频捕获问题。",
62+
enableMicrophone: "启用麦克风",
63+
close: "关闭语音捕捉",
64+
open: "开始语音捕捉",
4965
},
5066
ru: {
51-
speakNow: 'Говорите сейчас',
52-
noSpeech: 'Речь не обнаружена.',
53-
audioCapture: 'Проблема с захватом звука.',
54-
enableMicrophone: 'Включите микрофон',
67+
speakNow: "Говорите сейчас",
68+
noSpeech: "Речь не обнаружена.",
69+
audioCapture: "Проблема с захватом звука.",
70+
enableMicrophone: "Включите микрофон",
71+
close: "Закрыть захват голоса",
72+
open: "Начать захват голоса",
5573
},
5674
ar: {
57-
speakNow: 'تحدث الآن',
58-
noSpeech: 'لم يتم اكتشاف الكلام.',
59-
audioCapture: 'مشكلة في التقاط الصوت.',
60-
enableMicrophone: 'قم بتمكين الميكروفون',
75+
speakNow: "تحدث الآن",
76+
noSpeech: "لم يتم اكتشاف الكلام.",
77+
audioCapture: "مشكلة في التقاط الصوت.",
78+
enableMicrophone: "قم بتمكين الميكروفون",
79+
close: "إغلاق التقاط الصوت",
80+
open: "بدء التقاط الصوت",
6181
},
6282
ko: {
63-
speakNow: '지금 말하세요',
64-
noSpeech: '음성이 감지되지 않았습니다.',
65-
audioCapture: '오디오 캡처 문제.',
66-
enableMicrophone: '마이크를 활성화하세요',
83+
speakNow: "지금 말하세요",
84+
noSpeech: "음성이 감지되지 않았습니다.",
85+
audioCapture: "오디오 캡처 문제.",
86+
enableMicrophone: "마이크를 활성화하세요",
87+
close: "음성 캡처 닫기",
88+
open: "음성 캡처 시작",
6789
},
6890
nl: {
69-
speakNow: 'Spreek nu',
70-
noSpeech: 'Geen spraak gedetecteerd.',
71-
audioCapture: 'Probleem met audiovangst.',
72-
enableMicrophone: 'Activeer de microfoon',
91+
speakNow: "Spreek nu",
92+
noSpeech: "Geen spraak gedetecteerd.",
93+
audioCapture: "Probleem met audiovangst.",
94+
enableMicrophone: "Activeer de microfoon",
95+
close: "Stemopname sluiten",
96+
open: "Stemopname starten",
7397
},
7498
sv: {
75-
speakNow: 'Tala nu',
76-
noSpeech: 'Ingen tal upptäckt.',
77-
audioCapture: 'Problem med ljudinspelning.',
78-
enableMicrophone: 'Aktivera mikrofonen',
99+
speakNow: "Tala nu",
100+
noSpeech: "Ingen tal upptäckt.",
101+
audioCapture: "Problem med ljudinspelning.",
102+
enableMicrophone: "Aktivera mikrofonen",
103+
close: "Stäng röstinspelning",
104+
open: "Starta röstinspelning",
79105
},
80106
};

Diff for: src/components/VoiceCapture.vue

+32-10
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,26 @@
33
class="voicecapture"
44
:class="{ active: status, [mode]: mode }"
55
@click="deactivateVoice"
6+
aria-modal="true"
7+
role="dialog"
8+
:aria-expanded="status ? 'true' : 'false'"
69
>
7-
<button class="exit" type="button" @click="deactivateVoice">
8-
<i class="icon icon-exit">X</i>
10+
<button
11+
class="exit"
12+
@click="deactivateVoice"
13+
:aria-label="getTranslation('close')"
14+
type="button"
15+
>
16+
<i class="icon icon-exit" aria-hidden="true">X</i>
917
</button>
10-
<p class="text-tip">{{ translatedText }}</p>
18+
<p class="text-tip" aria-live="polite">{{ translatedText }}</p>
1119
<button
1220
type="button"
1321
class="btn-voice"
1422
:class="{ active: animationButton }"
23+
:aria-label="getTranslation('open')"
1524
>
16-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
25+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
1726
<path d="M17 11.998c0 2.76-2.23 5-4.99 5l-.002.002a4.994 4.994 0 01-4.979-5h-2c0 3.52 2.59 6.433 5.98 6.92v3.078h.01V22h2v-3.08h-.01A6.982 6.982 0 0019 11.998z" />
1827
<path fill="none" d="M0 0h24v24H0z" />
1928
<path d="M12 15c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v7c0 1.66 1.34 3 3 3z" />
@@ -41,6 +50,10 @@ export default {
4150
type: String,
4251
default: 'fullscreen',
4352
},
53+
clipboard: {
54+
type: Boolean,
55+
default: false,
56+
},
4457
},
4558
emits: ['voiceTranscript', 'onStatus'],
4659
setup(props, { emit }) {
@@ -62,12 +75,10 @@ export default {
6275
};
6376
6477
const deactivateVoice = () => {
65-
if (recognizing.value && recognition.value) {
66-
recognizing.value = false;
67-
animationButton.value = false;
68-
recognition.value.stop();
69-
emit('onStatus', false);
70-
}
78+
recognizing.value = false;
79+
animationButton.value = false;
80+
recognition.value.stop();
81+
emit('onStatus', false);
7182
};
7283
7384
const setupVoiceRecognition = () => {
@@ -123,6 +134,16 @@ export default {
123134
translatedText.value = interimTranscript || finalTranscript.value;
124135
125136
if (finalTranscript.value) {
137+
if(props.clipboard) {
138+
navigator.clipboard.writeText(finalTranscript.value).then(
139+
() => {
140+
console.log('Text copied to clipboard');
141+
},
142+
(err) => {
143+
console.error('Could not copy text to clipboard', err);
144+
}
145+
);
146+
}
126147
emit('voiceTranscript', finalTranscript.value);
127148
deactivateVoice();
128149
}
@@ -155,6 +176,7 @@ export default {
155176
translatedText,
156177
activateVoice,
157178
deactivateVoice,
179+
getTranslation
158180
};
159181
},
160182
};

0 commit comments

Comments
 (0)