refactor(locale-switcher): single flag-sized dropdown, drop 4-inline-flag UI
The nav previously showed 4 inline flag buttons (DE/EN/UK/RU) on desktop and a details-based dropdown on mobile. Martin asked for one dropdown with a trigger the size of a single flag, and the 4 inline flags to go away. - LocaleSwitcher: render a single <details class='locale-switcher'> everywhere; trigger is one flag + tiny caret; menu lists all 4 with labels. - Drop the 4-inline <ul> and the locale-switcher-mobile duplicate. - CSS: replace both blocks with one compact dropdown (flag-sized trigger, 44px touch target via padding, scrolled/transparent-nav variants). - Tests: assert 4 menu options, 5 flag SVGs, single <details> dropdown, active locale is a <span aria-current>, others are <a> with hreflang. - 141/141 PHPUnit green.
This commit is contained in:
@@ -11,20 +11,28 @@ use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Renders the language switcher widget and checks that:
|
||||
* - 4 items, one per supported locale,
|
||||
* - exactly one <details class="locale-switcher"> dropdown,
|
||||
* - 4 menu items, one per supported locale,
|
||||
* - the active locale is marked aria-current="true" and is a <span>,
|
||||
* - inactive locales are <a> links to /locale?set=...&return=...,
|
||||
* - every item contains a flag SVG,
|
||||
* - the trigger and every menu item contain a flag SVG,
|
||||
* - the rendered label is in the current locale's language.
|
||||
*/
|
||||
final class LocaleSwitcherTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function rendersFourItemsForAllSupportedLocales(): void
|
||||
public function rendersSingleDropdownForAllSupportedLocales(): void
|
||||
{
|
||||
$html = (new LocaleSwitcher('en', '/'))->render();
|
||||
self::assertStringContainsString('<ul class="locale-switcher"', $html);
|
||||
self::assertStringContainsString('<details class="locale-switcher-mobile"', $html);
|
||||
|
||||
// exactly one <details class="locale-switcher"> (no -mobile suffix, no desktop <ul>)
|
||||
self::assertStringContainsString('<details class="locale-switcher">', $html);
|
||||
self::assertStringNotContainsString('locale-switcher-mobile', $html);
|
||||
self::assertStringNotContainsString('<ul class="locale-switcher"', $html);
|
||||
self::assertStringNotContainsString('locale-switcher__item', $html);
|
||||
|
||||
// the menu lists all 4 supported locales
|
||||
self::assertSame(4, substr_count($html, 'class="locale-switcher__option'), 'expected 4 menu options');
|
||||
|
||||
// The 3 inactive locales render as <a hreflang="..">. The active
|
||||
// locale renders as <span lang=".."> (no hreflang). Together all
|
||||
@@ -35,10 +43,9 @@ final class LocaleSwitcherTest extends TestCase
|
||||
"locale '$code' is missing from switcher",
|
||||
);
|
||||
}
|
||||
// Both the desktop list and the mobile dropdown render a flag per locale
|
||||
self::assertSame(4, substr_count($html, 'class="locale-switcher__option'), 'expected 4 desktop options');
|
||||
self::assertSame(4, substr_count($html, 'class="locale-switcher-mobile__option'), 'expected 4 mobile options');
|
||||
self::assertSame(9, substr_count($html, 'class="flag"'), 'expected 9 flag SVGs (4 desktop + 4 mobile menu + 1 mobile trigger)');
|
||||
|
||||
// 1 flag in trigger + 4 flags in menu = 5 total
|
||||
self::assertSame(5, substr_count($html, 'class="flag"'), 'expected 5 flag SVGs (1 trigger + 4 menu)');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -129,4 +136,17 @@ final class LocaleSwitcherTest extends TestCase
|
||||
self::assertStringContainsString('aria-label="Sprache wählen"', $htmlDe);
|
||||
self::assertStringContainsString('aria-label="Choose language"', $htmlEn);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function triggerContainsCurrentLocaleFlag(): void
|
||||
{
|
||||
// The closed dropdown shows the current locale's flag in the trigger
|
||||
$html = (new LocaleSwitcher('de', '/'))->render();
|
||||
// The first <svg class="flag"> in the document is the trigger
|
||||
self::assertStringContainsString('<svg class="flag" viewBox="0 0 24 16"', $html);
|
||||
// The first flag SVG must contain the German colours
|
||||
$deFlag = LocaleSwitcher::flagSvg('de');
|
||||
$pos = strpos($html, $deFlag);
|
||||
self::assertNotFalse($pos, 'expected German flag SVG in the trigger (first <svg> in document)');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user