mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
fix(list-box): correct button/description translations based on selection count
The `ListBoxSelection` component now properly handles translations for the clear button based on the selected items: - Fix `buttonLabel` and `description` to use the same translation logic - Add tests for custom translations in both `ComboBox` and `MultiSelect`
This commit is contained in:
parent
9b61af0306
commit
5c332bae5e
4 changed files with 75 additions and 13 deletions
|
@ -44,13 +44,12 @@
|
||||||
$: if (ctx && ref) {
|
$: if (ctx && ref) {
|
||||||
ctx.declareRef({ key: "selection", ref });
|
ctx.declareRef({ key: "selection", ref });
|
||||||
}
|
}
|
||||||
|
$: translationId =
|
||||||
$: translationId = selectionCount
|
selectionCount === undefined
|
||||||
? translationIds.clearAll
|
? translationIds.clearSelection
|
||||||
: translationIds.clearSelection;
|
: translationIds.clearAll;
|
||||||
$: buttonLabel =
|
$: buttonLabel =
|
||||||
translateWithId?.(translationIds.clearAll) ??
|
translateWithId?.(translationId) ?? defaultTranslations[translationId];
|
||||||
defaultTranslations[translationIds.clearAll];
|
|
||||||
$: description =
|
$: description =
|
||||||
translateWithId?.(translationId) ?? defaultTranslations[translationId];
|
translateWithId?.(translationId) ?? defaultTranslations[translationId];
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ComboBox } from "carbon-components-svelte";
|
import { ComboBox } from "carbon-components-svelte";
|
||||||
import type { ComboBoxItem } from "carbon-components-svelte/ComboBox/ComboBox.svelte";
|
import type { ComponentProps } from "svelte";
|
||||||
|
|
||||||
export let items: ComboBoxItem[] = [
|
export let items: ComponentProps<ComboBox>["items"] = [
|
||||||
{ id: "0", text: "Slack" },
|
{ id: "0", text: "Slack" },
|
||||||
{ id: "1", text: "Email" },
|
{ id: "1", text: "Email" },
|
||||||
{ id: "2", text: "Fax" },
|
{ id: "2", text: "Fax" },
|
||||||
];
|
];
|
||||||
export let selectedId: string | undefined = undefined;
|
export let selectedId: ComponentProps<ComboBox>["selectedId"] = undefined;
|
||||||
export let value = "";
|
export let value = "";
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
export let invalid = false;
|
export let invalid = false;
|
||||||
|
@ -20,8 +20,12 @@
|
||||||
export let warnText = "";
|
export let warnText = "";
|
||||||
export let helperText = "";
|
export let helperText = "";
|
||||||
export let size: "sm" | "xl" | undefined = undefined;
|
export let size: "sm" | "xl" | undefined = undefined;
|
||||||
export let shouldFilterItem = (item: ComboBoxItem, value: string) =>
|
export let shouldFilterItem: ComponentProps<ComboBox>["shouldFilterItem"] = (
|
||||||
item.text.toLowerCase().includes(value.toLowerCase());
|
item,
|
||||||
|
value,
|
||||||
|
) => item.text.toLowerCase().includes(value.toLowerCase());
|
||||||
|
export let translateWithIdSelection: ComponentProps<ComboBox>["translateWithIdSelection"] =
|
||||||
|
undefined;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ComboBox
|
<ComboBox
|
||||||
|
@ -40,6 +44,7 @@
|
||||||
{warn}
|
{warn}
|
||||||
{warnText}
|
{warnText}
|
||||||
{shouldFilterItem}
|
{shouldFilterItem}
|
||||||
|
{translateWithIdSelection}
|
||||||
on:select={(e) => {
|
on:select={(e) => {
|
||||||
console.log("select", e.detail);
|
console.log("select", e.detail);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -60,13 +60,35 @@ describe("ComboBox", () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const clearButton = screen.getByRole("button", { name: /clear/i });
|
const clearButton = screen.getByRole("button", {
|
||||||
|
name: "Clear selected item",
|
||||||
|
});
|
||||||
await user.click(clearButton);
|
await user.click(clearButton);
|
||||||
|
|
||||||
expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String));
|
expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String));
|
||||||
expect(screen.getByRole("textbox")).toHaveValue("");
|
expect(screen.getByRole("textbox")).toHaveValue("");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should use custom translations when translateWithId is provided", () => {
|
||||||
|
const customTranslations = {
|
||||||
|
clearSelection: "Remove selected item",
|
||||||
|
clearAll: "Remove all items",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
render(ComboBox, {
|
||||||
|
props: {
|
||||||
|
selectedId: "1",
|
||||||
|
value: "Email",
|
||||||
|
translateWithIdSelection: (id) => customTranslations[id],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const clearButton = screen.getByRole("button", {
|
||||||
|
name: "Remove selected item",
|
||||||
|
});
|
||||||
|
expect(clearButton).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle disabled state", () => {
|
it("should handle disabled state", () => {
|
||||||
render(ComboBox, { props: { disabled: true } });
|
render(ComboBox, { props: { disabled: true } });
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ describe("MultiSelect", () => {
|
||||||
await toggleOption("C");
|
await toggleOption("C");
|
||||||
expect(nthRenderedOptionText(0)).toBe("A");
|
expect(nthRenderedOptionText(0)).toBe("A");
|
||||||
|
|
||||||
// The newly-selected item also shouldn’t move after the dropdown is closed
|
// The newly-selected item also shouldn't move after the dropdown is closed
|
||||||
// and reopened.
|
// and reopened.
|
||||||
await closeMenu();
|
await closeMenu();
|
||||||
await openMenu();
|
await openMenu();
|
||||||
|
@ -179,6 +179,42 @@ describe("MultiSelect", () => {
|
||||||
const input = screen.getByRole("combobox");
|
const input = screen.getByRole("combobox");
|
||||||
expect(input).toHaveValue("");
|
expect(input).toHaveValue("");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should show correct clear button label regardless of selection count", async () => {
|
||||||
|
render(MultiSelect, {
|
||||||
|
items,
|
||||||
|
selectedIds: ["0"],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
screen.getByLabelText("Clear all selected items"),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
|
||||||
|
await openMenu();
|
||||||
|
await toggleOption("Email");
|
||||||
|
expect(
|
||||||
|
screen.getByLabelText("Clear all selected items"),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should use custom translations when translateWithId is provided", async () => {
|
||||||
|
const customTranslations = {
|
||||||
|
clearSelection: "Remove selected item",
|
||||||
|
clearAll: "Remove all items",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
render(MultiSelect, {
|
||||||
|
items,
|
||||||
|
selectedIds: ["0"],
|
||||||
|
translateWithIdSelection: (id) => customTranslations[id],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByLabelText("Remove all items")).toBeInTheDocument();
|
||||||
|
|
||||||
|
await openMenu();
|
||||||
|
await toggleOption("Email");
|
||||||
|
expect(screen.getByLabelText("Remove all items")).toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("keyboard navigation", () => {
|
describe("keyboard navigation", () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue