Two cascading <select>s — the first picks a language, the second lists voices for that language. The chosen voice is persisted via the voice utility, so every <k-text-to-speech> on the page (and across reloads) uses it as a default when no voice attribute is set.
The language dropdown defaults to the browser's primary language (navigator.language) so a user almost always sees a relevant voice list immediately.
Just drop the element into a settings page or somewhere visible. Voices load asynchronously, so the dropdowns may briefly be empty before the rest populate.
<k-voice-selector></k-voice-selector>
Set language to override the default browser language. Accepts a primary language code (e.g. "fr", "es") or a full BCP‑47 tag (the primary part is used). The user can still switch via the dropdown afterward.
<k-voice-selector language="fr"></k-voice-selector>
Pick a voice in the dropdown, then click any <k-text-to-speech> on the page that doesn't have its own voice attribute — it'll use your saved preference. The choice persists across page reloads.
<k-voice-selector></k-voice-selector>
<k-text-to-speech text="This will use the voice you picked above"></k-text-to-speech>
The disabled attribute prevents user interaction. The dropdown also auto-disables when the browser doesn't support the SpeechSynthesis API.
<k-voice-selector disabled></k-voice-selector>
new VoiceSelector()window.speechSynthesislanguage: StringOptional initial language. If set, overrides the default navigator.language on first render. Accepts a primary language code ("en", "es") or a full BCP‑47 tag (the primary part is used). The user can change the language via the first dropdown afterward. Syncs to language attribute.
placeholder: StringLabel for the empty-selection option. Default is "Browser default". Syncs to placeholder attribute.
disabled: BooleanWhen true, the dropdown cannot be changed. Syncs to disabled attribute.
refresh(): voidForce a re-read of speechSynthesis.getVoices(). Rarely needed since the component subscribes to the voiceschanged event, but useful if you populate voices dynamically.
changeFires when the user picks a new voice. detail contains { voice: String } — the voice name, or empty string for "browser default". The voice utility is updated automatically; this event is for callers that want to react in addition.