From 1f10afac640421d2864089056c2790af984f481a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Wed, 30 Jun 2021 20:17:28 +0200 Subject: [PATCH] Simplify language selection with a few languages As mentioned in commit 5214d89c8, using the `change` event of a `select` field to automatically change location is really annoying for keyboard users, since the event will trigger when pressing the down key to navigate through the options or when typing a key to start searching for an option. This might cause a lot of frustration. Most multilanguage CONSUL sites enable between 2 and 4 languages. In these cases, it's easier to just display the list of languages to simplify the selection. This way in this situation we also make it clear which languages are available. If we use a ` - <%= options_for_select(language_options, current_path_with_query_params(locale: I18n.locale)) %> - - + <% if many_locales? %> +
+ + +
+ <% else %> +

<%= label %>

+ + <%= link_list(*language_links, "aria-labelledby": label_id) %> + <% end %> diff --git a/app/components/layout/locale_switcher_component.rb b/app/components/layout/locale_switcher_component.rb index 1983e176b..4e7408adf 100644 --- a/app/components/layout/locale_switcher_component.rb +++ b/app/components/layout/locale_switcher_component.rb @@ -1,5 +1,5 @@ class Layout::LocaleSwitcherComponent < ApplicationComponent - delegate :name_for_locale, :current_path_with_query_params, to: :helpers + delegate :name_for_locale, :link_list, :current_path_with_query_params, to: :helpers def render? locales.size > 1 @@ -7,13 +7,36 @@ class Layout::LocaleSwitcherComponent < ApplicationComponent private + def many_locales? + locales.size > 4 + end + def locales I18n.available_locales end - def language_options + def label + t("layouts.header.locale") + end + + def label_id + "locale_switcher_label" + end + + def language_links locales.map do |locale| - [name_for_locale(locale), current_path_with_query_params(locale: locale), lang: locale] + [ + name_for_locale(locale), + current_path_with_query_params(locale: locale), + locale == I18n.locale, + lang: locale + ] + end + end + + def language_options + language_links.map do |text, path, _, options| + [text, path, options] end end end diff --git a/spec/components/layout/locale_switcher_component_spec.rb b/spec/components/layout/locale_switcher_component_spec.rb index c4ae8b1be..5d1462e49 100644 --- a/spec/components/layout/locale_switcher_component_spec.rb +++ b/spec/components/layout/locale_switcher_component_spec.rb @@ -28,6 +28,7 @@ describe Layout::LocaleSwitcherComponent, type: :component do expect(page).to have_css "form" expect(page).to have_select "Language:", options: %w[Deutsch English Español Français Nederlands] + expect(page).not_to have_css "ul" end it "selects the current locale" do @@ -53,4 +54,27 @@ describe Layout::LocaleSwitcherComponent, type: :component do end end end + + context "with a few languages" do + before do + allow(I18n).to receive(:available_locales).and_return(%i[en es fr]) + end + + it "renders a list of links" do + render_inline component + + expect(page).to have_css "ul" + expect(page).to have_link "English", href: "/?locale=en" + expect(page).to have_link "Español", href: "/?locale=es" + expect(page).to have_link "Français", href: "/?locale=fr" + expect(page).not_to have_css "form" + end + + it "marks the current locale" do + render_inline component + + expect(page).to have_css "[aria-current]", count: 1 + expect(page).to have_css "[aria-current]", exact_text: "English" + end + end end