fix: language buttons real design / conformance
This commit is contained in:
1 parent
2c8f39273c
commit
0490a4c494
23 files changed
+1408
-412
No files matched your search
@@ -0,0 +1,172 @@
|
||||
Feature: Language switcher conforms to the official design
|
||||
|
||||
Background:
|
||||
Given the design in docs/design is the visual spec of record for LanguageSwitcher and UserMenu
|
||||
And the interface supports exactly two languages, English and Français
|
||||
And each language is always written in its own name, whatever the interface language
|
||||
And the language rules of features/spa_internationalization.feature still apply
|
||||
And the language control no longer uses a form select anywhere
|
||||
And no language preference is sent to the server
|
||||
|
||||
Scenario Outline: Account menu lists Profile, Theme, Language and Log out in design order
|
||||
Given a signed-in user opens the account menu in the <surface>
|
||||
Then the entries appear in this order
|
||||
| Profile |
|
||||
| separator |
|
||||
| "Theme" section label |
|
||||
| System, Light, Dark |
|
||||
| separator |
|
||||
| "Language" section label |
|
||||
| English, Français |
|
||||
| separator |
|
||||
| Log out |
|
||||
And the "Theme" and "Language" labels are 11 px, weight 500, uppercase, letter-spacing 0.04em and --ui-text-muted
|
||||
And the label padding is <label_padding>
|
||||
And the menu is <size>
|
||||
And every item row is <row_height> high
|
||||
|
||||
Examples:
|
||||
| surface | label_padding | size | row_height |
|
||||
| desktop UserMenu popover | 6px 8px 2px | a 224 px popover above the chip | 32 px |
|
||||
| mobile AccountMenuSheet | 8px 16px 2px | a bottom sheet with grab handle | 48 px |
|
||||
|
||||
Scenario Outline: Language rows are a radio group naming each language in its own name
|
||||
Given the interface language is <locale>
|
||||
When the account menu is open in the <surface>
|
||||
Then the "Language" label names a group of two menuitemradio rows
|
||||
And the rows read "English" with lang "en" and "Français" with lang "fr"
|
||||
And the row for <locale_name> has aria-checked "true" and a check icon at the right edge
|
||||
And the other row has aria-checked "false" and no check icon
|
||||
And no Nuxt UI select, combobox or languages icon row is present in the menu
|
||||
|
||||
Examples:
|
||||
| surface | locale | locale_name |
|
||||
| desktop UserMenu popover | en | English |
|
||||
| desktop UserMenu popover | fr | Français |
|
||||
| mobile AccountMenuSheet | en | English |
|
||||
| mobile AccountMenuSheet | fr | Français |
|
||||
|
||||
Scenario Outline: Theme rows are radio items that keep the menu open
|
||||
Given the theme preference is <preference>
|
||||
When the account menu is open in the <surface>
|
||||
Then System, Light and Dark are menuitemradio rows in a group named "Theme"
|
||||
And only the <preference> row has aria-checked "true" and a check icon
|
||||
When the user chooses another theme row
|
||||
Then the theme applies at once and the menu stays open
|
||||
|
||||
Examples:
|
||||
| surface | preference |
|
||||
| desktop UserMenu popover | light |
|
||||
| mobile AccountMenuSheet | dark |
|
||||
|
||||
Scenario Outline: Choosing a language in the account menu applies it at once and keeps the menu open
|
||||
Given the interface language is en and the user is on /profile with an unsaved display name "Alice B."
|
||||
And the account menu is open in the <surface>
|
||||
When the user chooses "Français"
|
||||
Then all interface text, including the menu labels "Thème" and "Langue", is French
|
||||
And the document lang is "fr" and localStorage "renewcms-language" is "fr"
|
||||
And the Français row is checked and the menu stays open
|
||||
And the route, session, theme and unsaved display name are unchanged
|
||||
And no reload, navigation or /v1 request occurs
|
||||
When the user chooses "English"
|
||||
Then the interface is English, the document lang is "en" and the menu stays open
|
||||
|
||||
Examples:
|
||||
| surface |
|
||||
| desktop UserMenu popover |
|
||||
| mobile AccountMenuSheet |
|
||||
|
||||
Scenario Outline: Account menu keyboard and dismissal
|
||||
Given the account menu is open in the <surface>
|
||||
When the user moves with ArrowDown and ArrowUp
|
||||
Then focus visits Profile, the theme rows, the language rows and Log out in visual order and wraps at the ends
|
||||
When the user presses Enter or Space on a language row
|
||||
Then that language is applied and the menu stays open
|
||||
When the user presses Escape or clicks outside
|
||||
Then the menu closes without changing the language
|
||||
|
||||
Examples:
|
||||
| surface |
|
||||
| desktop UserMenu popover |
|
||||
| mobile AccountMenuSheet |
|
||||
|
||||
Scenario Outline: Auth footer shows the language chip beside the theme chip
|
||||
Given the user is signed out on <route>
|
||||
And the interface language is en
|
||||
Then the footer outside the card contains the language chip and the System theme chip aligned right with an 8 px gap
|
||||
And any existing footer slot content stays to the left of the chips
|
||||
And the chip shows the lucide languages icon at 14 px followed by "English"
|
||||
And the chip has a 1 px --ui-border-accented border, --ui-text-toned text, aria-haspopup "menu", aria-expanded "false" and aria-label "Language: English"
|
||||
And no language select is rendered in the card or the footer
|
||||
|
||||
Examples:
|
||||
| route |
|
||||
| /login |
|
||||
| /register |
|
||||
| /register/pending |
|
||||
| /register/validate |
|
||||
| /register/reset/request |
|
||||
| /register/reset/validate |
|
||||
| /invite/accept |
|
||||
|
||||
Scenario Outline: Auth footer is always rendered, on mobile too
|
||||
Given the viewport is <viewport>
|
||||
When an auth screen with no footer slot content renders
|
||||
Then the footer with the language chip and the theme chip is visible
|
||||
And the chip is <chip_height> high
|
||||
|
||||
Examples:
|
||||
| viewport | chip_height |
|
||||
| 1440 x 900 | 28 px |
|
||||
| 390 x 844 | 44 px |
|
||||
|
||||
Scenario: Chip reflects the current language
|
||||
Given the stored language is fr
|
||||
When /login renders
|
||||
Then the chip reads "Français" and its aria-label is "Langue : Français"
|
||||
|
||||
Scenario Outline: Auth language popover
|
||||
Given the user is signed out on /login in <locale_name>
|
||||
When the user activates the language chip
|
||||
Then the chip has aria-expanded "true" and --ui-bg-elevated
|
||||
And a popover with role "menu" named "Language" opens above the chip, right-aligned and 36 px above its bottom edge, 168 px wide, --ui-bg, 1 px --ui-border, --rc-shadow-pop and 4 px padding
|
||||
And it holds menuitemradio rows "English" (lang "en") and "Français" (lang "fr") that are 32 px high on desktop and 44 px on mobile
|
||||
And the current language row has aria-checked "true" and a 16 px check icon at the right edge
|
||||
|
||||
Examples:
|
||||
| locale_name |
|
||||
| English |
|
||||
| Français |
|
||||
|
||||
Scenario: Choosing a language in the auth popover closes it
|
||||
Given the auth language popover is open on /login with English current
|
||||
When the user chooses "Français"
|
||||
Then the whole screen is French at once, including the card, the footer and the document title
|
||||
And the document lang is "fr" and localStorage "renewcms-language" is "fr"
|
||||
And the popover closes and focus returns to the language chip
|
||||
And the chip reads "Français"
|
||||
And the form values already typed, the route and the theme are unchanged
|
||||
And no /v1 request occurs
|
||||
|
||||
Scenario: Dismiss the auth popover without changing language
|
||||
Given the auth language popover is open
|
||||
When the user presses Escape or clicks outside it
|
||||
Then it closes, aria-expanded is "false" and the language is unchanged
|
||||
And focus returns to the chip on Escape
|
||||
|
||||
Scenario: Auth popover keyboard
|
||||
Given the language chip has focus
|
||||
When the user presses Enter, Space or ArrowDown
|
||||
Then the popover opens with focus on the current language row
|
||||
And ArrowUp and ArrowDown move between the two rows and Enter or Space chooses one
|
||||
|
||||
Scenario: Language persists across public and signed-in screens
|
||||
Given the user chose Français on /login
|
||||
When they sign in, open the account menu and log out
|
||||
Then Français is checked in the account menu and the /login chip reads "Français" again
|
||||
And a storage failure still lets the choice apply for the current session, as in spa_internationalization
|
||||
|
||||
Scenario: Catalog parity for the new strings
|
||||
Then the en and fr catalogs contain "Theme" and "Language: {0}"
|
||||
And "Language: {0}" keeps its {0} parameter in French
|
||||
And the strings "English" and "Français" are not translated
|
||||
Reference in new issue
Block a user