Skip to content

✨ Add labelFormat and header options to LocaleSwitcher - #29

Merged
damienlagae merged 1 commit into
mainfrom
feat/locale-switcher-label-and-header
Jul 31, 2026
Merged

damienlagae merged 1 commit into
mainfrom
feat/locale-switcher-label-and-header

Conversation

@damienlagae

Copy link
Copy Markdown
Member

Problem

Apps carrying three or more locales cannot afford the full own-language name in the navbar — English / Français / Nederlands eats the space the menu items need — but the only alternative today, showLocaleName: false, leaves a bare flag with no textual cue at all.

So every app migrating off enabel/layout-bundle hand-rolls the same dropdown to get flag + short code + a "Change language" heading back. That is exactly what this component should provide.

There is also a rendering bug: flags were forced into a 1.5rem square. The cif:* set has no single aspect ratio (cif:nl is 2:1, cif:gb is 3:2), so the flag was letterboxed inside its own box and the border framed empty space rather than the flag:

Before After
square box, flag shrunk and centred inside it 4:3 box, flag fills it, rounding hugs the flag

Changes

  • labelFormatname (default, unchanged), code (EN) or none (flag only).
  • header — optional dropdown-header at the top of the menu, e.g. 'Change language'. Translate at the call site. Defaults to null, so nothing renders unless asked.
  • Flags render rounded with a subtle border and carry the locale's own-language name as title, so labelFormat: 'none' stays accessible.
  • Flags render in a fixed 4:3 box (1.5rem × 1.125rem) with preserveAspectRatio="xMidYMid slice". Both width and height are explicit: a host application's ux_icons.default_icon_attributes (commonly width/height: 1em) otherwise wins and forces the square back — width: auto is not enough.
{{ component('Enabel:Ux:LocaleSwitcher', {
    locales: enabled_locales,
    labelFormat: 'code',
    header: 'navigation.language.change'|trans,
}) }}

Renders 🇬🇧 EN in the navbar, and a dropdown headed Change language listing 🇫🇷 FR and 🇳🇱 NL.

Backward compatibility

showLocaleName keeps working — labelFormat is derived from it, so a call site passing false still resolves to none. An explicit labelFormat always wins. The property is marked @deprecated rather than removed, and its existing tests still pass untouched.

The only visual change for callers who pass nothing is the flag styling (correct aspect ratio, rounded, bordered, title); the label still defaults to the own-language name.

Verification

  • vendor/bin/phpunit253 tests, 684 assertions, green (7 new LocaleSwitcher tests covering the derivation, the precedence rule, and the rejected values).
  • php-cs-fixer and phpstan clean.
  • Rendered in a real Symfony 8 app across /en, /fr and /nl: verified the emitted DOM carries title per locale, the rounded border border-dark-subtle classes, hrefs /fr and /nl, the heading, and a 24×18 flag box.

Drive-by

The docs documented the parameter as show_locale_name; the component has always read showLocaleName.

Apps carrying three or more locales cannot afford the full own-language
name in the navbar — "English / Français / Nederlands" eats the space the
menu items need — but dropping to `showLocaleName: false` leaves a bare
flag with no textual cue at all. Travel and the other apps migrating off
enabel/layout-bundle all hand-rolled the same dropdown to get flag + short
code back, which is exactly what this component should provide.

- `labelFormat`: `name` (default, unchanged), `code` (EN) or `none`.
- `header`: optional `dropdown-header` at the top of the menu, e.g.
  "Change language". Translate at the call site.

Flags now render rounded with a subtle border and carry the locale's
own-language name as `title`, so `labelFormat: 'none'` stays accessible and
the flags read as deliberate chips rather than bare squares.

They also render in a fixed 4:3 box with preserveAspectRatio="xMidYMid
slice" instead of a 1.5rem square. The cif:* set has no single aspect ratio
(cif:nl is 2:1, cif:gb is 3:2), so a square box letterboxed the flag inside
its own border — the rounding and the border framed empty space rather than
the flag. Width and height are both explicit because a host application's
ux_icons.default_icon_attributes (commonly width/height 1em) would
otherwise win and force the square back.

`showLocaleName` keeps working: `labelFormat` derives from it, so passing
`false` still resolves to `none`. An explicit `labelFormat` wins. The
property is marked deprecated rather than removed.

Also fixes the docs, which documented the parameter as `show_locale_name`
while the component has always read `showLocaleName`.
@damienlagae
damienlagae merged commit 959094c into main Jul 31, 2026
9 checks passed
@damienlagae
damienlagae deleted the feat/locale-switcher-label-and-header branch July 31, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant