diff --git a/web/src/components/l10n/LocaleSelector.jsx b/web/src/components/l10n/LocaleSelector.jsx
index 40d9a4e0a7..db93e53a2b 100644
--- a/web/src/components/l10n/LocaleSelector.jsx
+++ b/web/src/components/l10n/LocaleSelector.jsx
@@ -22,33 +22,13 @@
import React, { useState } from "react";
import { _ } from "~/i18n";
-import { ListSearch } from "~/components/core";
+import { ListSearch, Selector } from "~/components/core";
import { noop } from "~/utils";
/**
* @typedef {import ("~/client/l10n").Locale} Locale
*/
-const ListBox = ({ children, ...props }) => {
- return (
-
- );
-};
-
-const ListBoxItem = ({ isSelected, children, onClick, ...props }) => {
- if (isSelected) props['aria-selected'] = true;
-
- return (
-
- {children}
-
- );
-};
-
/**
* Content for a locale item.
* @component
@@ -58,11 +38,11 @@ const ListBoxItem = ({ isSelected, children, onClick, ...props }) => {
*/
const LocaleItem = ({ locale }) => {
return (
- <>
+
{locale.name}
{locale.territory}
{locale.id}
- >
+
);
};
@@ -80,23 +60,26 @@ export default function LocaleSelector({ value, locales = [], onChange = noop })
const [filteredLocales, setFilteredLocales] = useState(locales);
const searchHelp = _("Filter by language, territory or locale code");
+ const onSelectionChange = (selection) => onChange(selection[0]);
return (
<>
-
- { filteredLocales.map((locale, index) => (
- onChange(locale.id)}
- isSelected={locale.id === value}
- >
+
+ { filteredLocales.map((locale) => (
+
-
+
))}
-
+
>
);
}
diff --git a/web/src/components/l10n/LocaleSelector.test.jsx b/web/src/components/l10n/LocaleSelector.test.jsx
new file mode 100644
index 0000000000..b401c336f5
--- /dev/null
+++ b/web/src/components/l10n/LocaleSelector.test.jsx
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) [2024] SUSE LLC
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, contact SUSE LLC.
+ *
+ * To contact SUSE LLC about this file by physical or electronic mail, you may
+ * find current contact information at www.suse.com.
+ */
+
+import React from "react";
+import { act, screen, waitFor, within } from "@testing-library/react";
+import { plainRender } from "~/test-utils";
+import { LocaleSelector } from "~/components/l10n";
+
+const locales = [
+ { id: "es_ES", name: "Spanish", territory: "Spain" },
+ { id: "en_US", name: "English", territory: "United States" }
+];
+
+const onChange = jest.fn();
+
+describe("LocaleSelector", () => {
+ it("renders a selector for given locales displaying their name, territory, and id", () => {
+ plainRender(
+
+ );
+
+ const selector = screen.getByRole("grid", { name: "Available locales" });
+
+ const options = within(selector).getAllByRole("row");
+ expect(options.length).toEqual(locales.length);
+
+ within(selector).getByRole("row", { name: "Spanish Spain es_ES" });
+ within(selector).getByRole("row", { name: "English United States en_US" });
+ });
+
+ it("renders an input for filtering locales", async () => {
+ const { user } = plainRender(
+
+ );
+
+ const filterInput = screen.getByRole("search");
+ screen.getByRole("row", { name: "English United States en_US" });
+
+ await act(async () => await user.type(filterInput, "Span"));
+ await waitFor(() => {
+ const englishOption = screen.queryByRole("row", { name: "English United States en_US" });
+ expect(englishOption).not.toBeInTheDocument();
+ });
+ });
+
+ describe("when user clicks an option", () => {
+ it("calls the #onChange callback with the locale id", async () => {
+ const { user } = plainRender(
+
+ );
+
+ const selector = screen.getByRole("grid", { name: "Available locales" });
+ const english = within(selector).getByRole("row", { name: "English United States en_US" });
+ await user.click(english);
+
+ expect(onChange).toHaveBeenCalledWith("en_US");
+ });
+ });
+});