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"); + }); + }); +});