diff --git a/tests/Dropdown.test.svelte b/tests/Dropdown.test.svelte
deleted file mode 100644
index 3ba410d6..00000000
--- a/tests/Dropdown.test.svelte
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
- {
- console.log(e.detail.selectedId);
- }}
- translateWithId={(id) => {
- console.log(id); // "open" | "close"
- return id;
- }}
- let:item
- let:index
->
- {item.id}
- {index}
-
-
- {
- return item.text + " (" + item.id + ")";
- }}
- titleText="Contact"
- selectedId="0"
- items={itemsWithoutConst}
-/>
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/Dropdown/Dropdown.test.svelte b/tests/Dropdown/Dropdown.test.svelte
new file mode 100644
index 00000000..6e5663f9
--- /dev/null
+++ b/tests/Dropdown/Dropdown.test.svelte
@@ -0,0 +1,53 @@
+
+
+
diff --git a/tests/Dropdown/Dropdown.test.ts b/tests/Dropdown/Dropdown.test.ts
new file mode 100644
index 00000000..4154d81e
--- /dev/null
+++ b/tests/Dropdown/Dropdown.test.ts
@@ -0,0 +1,266 @@
+import { render, screen } from "@testing-library/svelte";
+import { user } from "../setup-tests";
+import Dropdown from "./Dropdown.test.svelte";
+import DropdownSlot from "./DropdownSlot.test.svelte";
+
+const items = [
+ { id: "0", text: "Slack" },
+ { id: "1", text: "Email" },
+ { id: "2", text: "Fax" },
+] as const;
+
+describe("Dropdown", () => {
+ it("should render with default props", () => {
+ render(Dropdown, {
+ props: { items, selectedId: "0", titleText: "Contact" },
+ });
+
+ expect(screen.getByText("Contact")).toBeInTheDocument();
+ const button = screen.getByRole("button");
+ expect(button.querySelector(".bx--list-box__label")).toHaveTextContent(
+ "Slack",
+ );
+ });
+
+ it("should handle custom item display text", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ titleText: "Contact",
+ itemToString: (item) => `${item.text} (${item.id})`,
+ },
+ });
+
+ const button = screen.getByRole("button");
+ expect(button.querySelector(".bx--list-box__label")).toHaveTextContent(
+ "Slack (0)",
+ );
+ });
+
+ it("should handle hidden label", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ titleText: "Contact",
+ hideLabel: true,
+ },
+ });
+
+ const label = screen.getByText("Contact");
+ expect(label).toHaveClass("bx--visually-hidden");
+ });
+
+ it("should handle light variant", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ light: true,
+ },
+ });
+
+ const button = screen.getByRole("button");
+ expect(button.closest(".bx--dropdown")).toHaveClass("bx--dropdown--light");
+ });
+
+ it("should handle inline variant", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ type: "inline",
+ },
+ });
+
+ const button = screen.getByRole("button");
+ expect(button).toBeEnabled();
+ expect(button).toHaveTextContent("Slack");
+ expect(button.closest(".bx--dropdown__wrapper")).toHaveClass(
+ "bx--dropdown__wrapper--inline",
+ );
+ });
+
+ it("should handle size variants", async () => {
+ const { rerender } = render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ size: "sm",
+ },
+ });
+
+ const button = screen.getByRole("button");
+ expect(button.closest(".bx--dropdown")).toHaveClass("bx--dropdown--sm");
+
+ await rerender({ items, selectedId: "0", size: "xl" });
+ expect(button.closest(".bx--dropdown")).toHaveClass("bx--dropdown--xl");
+ });
+
+ it("should handle invalid state", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ invalid: true,
+ invalidText: "Invalid selection",
+ },
+ });
+
+ const button = screen.getByRole("button");
+ expect(button).toBeEnabled();
+ expect(button).toHaveTextContent("Slack");
+ expect(button.closest(".bx--dropdown")).toHaveAttribute(
+ "data-invalid",
+ "true",
+ );
+ expect(screen.getByText("Invalid selection")).toBeInTheDocument();
+ });
+
+ it("should handle warning state", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ warn: true,
+ warnText: "Warning message",
+ },
+ });
+
+ const button = screen.getByRole("button");
+ expect(button).toBeEnabled();
+ expect(button).toHaveTextContent("Slack");
+ expect(button.closest(".bx--dropdown")).toHaveClass(
+ "bx--dropdown--warning",
+ );
+ expect(screen.getByText("Warning message")).toBeInTheDocument();
+ });
+
+ it("should handle disabled state", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ disabled: true,
+ },
+ });
+
+ expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
+ expect(screen.getByRole("button")).toHaveAttribute("disabled");
+ expect(screen.getByRole("button")).toHaveTextContent("Slack");
+ });
+
+ it("should handle helper text", () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ helperText: "Help text",
+ },
+ });
+
+ expect(screen.getByText("Help text")).toHaveClass("bx--form__helper-text");
+ });
+
+ it("should handle item selection", async () => {
+ const { component } = render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ },
+ });
+
+ const selectHandler = vi.fn();
+ component.$on("select", selectHandler);
+
+ const button = screen.getByRole("button");
+ await user.click(button);
+
+ const menuItemText = screen.getByText("Email");
+ const menuItem = menuItemText.closest(".bx--list-box__menu-item");
+ expect(menuItem).not.toBeNull();
+ await user.click(menuItem!);
+
+ expect(selectHandler).toHaveBeenCalledWith(
+ expect.objectContaining({
+ detail: { selectedId: "1", selectedItem: items[1] },
+ }),
+ );
+ });
+
+ it("should handle keyboard navigation", async () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ },
+ });
+
+ const button = screen.getByRole("button");
+ await user.tab();
+ expect(button).toHaveFocus();
+
+ await user.keyboard("{Enter}");
+ expect(screen.getByRole("listbox")).toBeVisible();
+ expect(screen.getByRole("option", { selected: true })).toHaveTextContent(
+ "Slack",
+ );
+
+ await user.keyboard("{ArrowDown}{ArrowDown}");
+ await user.keyboard("{Enter}");
+
+ expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
+ expect(button).toHaveTextContent("Email");
+ });
+
+ it("should handle disabled items", async () => {
+ const itemsWithDisabled = [
+ { id: "0", text: "Slack" },
+ { id: "1", text: "Email", disabled: true },
+ { id: "2", text: "Fax" },
+ ];
+
+ render(Dropdown, {
+ props: {
+ items: itemsWithDisabled,
+ selectedId: "0",
+ },
+ });
+
+ const button = screen.getByRole("button");
+ await user.click(button);
+
+ const menuItemText = screen.getByText("Email");
+ const menuItem = menuItemText.closest(".bx--list-box__menu-item");
+ expect(menuItem).not.toBeNull();
+ expect(menuItem).toHaveAttribute("disabled");
+ });
+
+ it("should handle custom slot content", async () => {
+ render(DropdownSlot);
+
+ await user.click(screen.getByRole("button"));
+
+ const customItems = screen.getAllByTestId("custom-item");
+ expect(customItems).toHaveLength(3);
+ expect(customItems[0]).toHaveTextContent("Item 1: Option 1");
+ expect(customItems[1]).toHaveTextContent("Item 2: Option 2");
+ expect(customItems[2]).toHaveTextContent("Item 3: Option 3");
+ });
+
+ it("should close on outside click", async () => {
+ render(Dropdown, {
+ props: {
+ items,
+ selectedId: "0",
+ },
+ });
+
+ await user.click(screen.getByRole("button"));
+ expect(screen.getByRole("listbox")).toBeVisible();
+
+ await user.click(document.body);
+ expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
+ });
+});
diff --git a/tests/Dropdown/DropdownSlot.test.svelte b/tests/Dropdown/DropdownSlot.test.svelte
new file mode 100644
index 00000000..7be8caad
--- /dev/null
+++ b/tests/Dropdown/DropdownSlot.test.svelte
@@ -0,0 +1,25 @@
+
+
+
+
+ Item {index + 1}: {item.text}
+
+