feat(editor): split voice Language dropdown into Language + Accent selects#567
Open
galbus wants to merge 5 commits into
Open
feat(editor): split voice Language dropdown into Language + Accent selects#567galbus wants to merge 5 commits into
galbus wants to merge 5 commits into
Conversation
…lects
The combined "English (American)" Language dropdown becomes a Language
(name) select plus an Accent select in both editors — the first slice of
replicating the BeyondWords dashboard voice filters (Language / Accent /
Native / Type / Gender).
- Block editor: Language lists each distinct language name; a
conditional Accent select lists the accents for the chosen name and
carries the language code. Both derive from the stored
beyondwords_language_code — no new persisted state. Picking a name
auto-selects its first accent, which stores the resolved code and
seeds that language's default body voice.
- Classic editor: mirrored. The name select is client-side only; the
Accent select keeps the beyondwords_language_code id/name so save()
and the submitted form are unchanged. Slim language rows are localized
for the Accent rebuild; the project-default flow selects name + accent
for the default code.
- The Accent select hides when a language offers a single accent while
still submitting that accent's code; with no language chosen a single
empty option keeps the field posting ('' = no language).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
…nt split The settings-panel block spec also exercises the Voice section and still asserted the combined "English (American)" label. Assert the split Language (English) + Accent (American) selects instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…en selects When the Language or Accent changed, the block editor kept rendering the previous language's Model + Voice dropdowns (from the stale store) with the loading Spinner wedged above them. Now, while the voices resolve, the Model + Voice fields are hidden and the Spinner takes their place, so it never appears between two select fields, matching the classic editor (which already clears Model/Voice and shows its loader at the bottom). The fields are hidden via a CSS class rather than unmounted, so the select keeps its DOM identity across the resolve and does not detach mid-interaction when the fetch completes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a Native select above the Model dropdown in both editors. It narrows the Voice list to voices native to the selected language (their primary language) and defaults to native-only; "All" adds the multilingual (non-native) voices back. This is the main lever for the "voice list is too long" feedback. - Filtering is client-side over the fetched voices (the API returns primary + secondary), mirrored across the block editor (voice-section.js + helpers.js), the classic editor (classic-metabox.js) and the PHP server-render (class-select-voice.php). - The selected voice is always kept, so toggling the filter never drops it; on load the filter opens on "All" when the saved voice is not native to the language (older posts, multilingual defaults) so it stays visible. - Type and Gender filters are intentionally out of scope for now. Tests: a non-native voice (Klaus, German-primary) is added to the mock; block + classic Cypress cover default-native hiding it and "All" revealing it, plus the saved-non-native seed; PHPUnit covers the native helpers and the "All" seed. Coverage 91.03%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntrol
The Spinner now stands in for whatever is still loading below the last
resolved control, and never sits between two select fields:
- while the languages load, only a Spinner shows;
- Language + Accent + Native show while the voices resolve, with the
Spinner in place of the Model + Voice group;
- once the voices resolve, Model + Voice show and the Spinner clears.
Model and Voice come from the same voices fetch, so they resolve
together (picking a Model filters the loaded list client-side).
Uses hasFinishedResolution (monotonic false->true) instead of
isResolving, which flips on and off and left a one-frame window where
stale Model/Voice options flashed. The Model + Voice group is kept
mounted and hidden with an inline style, so the <select> keeps its DOM
identity (no detach mid-interaction) and the hide can't lose a CSS
specificity battle with the component's own styles. Matches the classic
editor, which already clears Model/Voice and shows its loader in place.
Post meta is unchanged: only the language code and voice id are stored;
Language name, Accent, Model and the Native filter are all derived from
those on load, so nothing else needs persisting.
Tests: block + classic Cypress delay the voices response and assert the
Spinner/loader replaces Model + Voice while they resolve.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First slice of the dashboard-parity voice filters (Language / Accent / Native / Type / Gender): split the combined "English (American)" Language dropdown into a Language (name) select + an Accent select, in both editors.
voice-section.js+helpers.js): Language lists each distinct language name; a conditional Accent select lists the accents for the chosen name and carries the language code. Both derive from the storedbeyondwords_language_code— no new persisted state. Picking a name auto-selects its first accent, which stores the resolved code and seeds that language's default body voice (existing behaviour).class-select-voice.php+classic-metabox.js+class-assets.php): mirrored. The new name select is client-side only (nonameattribute); the Accent select keeps thebeyondwords_language_codeid/name, sosave()and the submitted form are unchanged. Slim language rows are localized so the Accent rebuild needs no extra API round-trip. The project-default flow now selects the name + accent for the default code.''= no language).Persistence is unchanged: only
beyondwords_language_code(resolved code) +beyondwords_body_voice_idare stored. Model/Voice behaviour is untouched.Why
Review feedback: the voice list is too long — we're replicating the BeyondWords dashboard's voice filters ([Language] [Accent] [Native] [Type] [Gender]). Language + Accent is the first vertical slice; Native/Type/Gender follow on separate branches.
Test plan
element()assertions (79-name select, 14 English accents, en_US/en_GB option positions) and new unit tests forlanguage_names()/accents_for_name()/find_language_by_code()/languages_for_script().classic-editor/select-voice.cy.js: 12/12 passing, incl. two new tests — name change auto-selects the first accent + hides Accent for single-accent languages (Welsh); accent change re-fetches voices and seeds the default voice (en_GB → Ollie/Legacy).block-editor/select-voice.cy.js: 7/7 passing (full publish flow across Post/Page/CPT with the split selects), incl. a new hide-Accent-for-single-accent-language test.phpcsclean on changed PHP;eslint+prettierclean on changed JS;npm run buildcompiles.🤖 Generated with Claude Code