diff --git a/tests/RadioTile.test.svelte b/tests/RadioTile.test.svelte
deleted file mode 100644
index 45356d3b..00000000
--- a/tests/RadioTile.test.svelte
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- {
- console.log(e.detail); // string
- }}
->
- Lite plan
- Standard plan
- Plus plan
-
diff --git a/tests/RadioTile/RadioTile.group.test.svelte b/tests/RadioTile/RadioTile.group.test.svelte
new file mode 100644
index 00000000..defafb8a
--- /dev/null
+++ b/tests/RadioTile/RadioTile.group.test.svelte
@@ -0,0 +1,25 @@
+
+
+
+ {#each values as value}
+ {value}
+ {/each}
+
+
+
+ Selected: {selected}
+
+
+
diff --git a/tests/RadioTile/RadioTile.single.test.svelte b/tests/RadioTile/RadioTile.single.test.svelte
new file mode 100644
index 00000000..6a986a02
--- /dev/null
+++ b/tests/RadioTile/RadioTile.single.test.svelte
@@ -0,0 +1,7 @@
+
+
+
+ Custom content
+
diff --git a/tests/RadioTile/RadioTile.test.svelte b/tests/RadioTile/RadioTile.test.svelte
new file mode 100644
index 00000000..84d734e4
--- /dev/null
+++ b/tests/RadioTile/RadioTile.test.svelte
@@ -0,0 +1,43 @@
+
+
+
+ {
+ console.log("change");
+ }}
+ on:keydown
+ on:click
+ on:mouseover
+ on:mouseenter
+ on:mouseleave
+ >
+ Test content
+
+
diff --git a/tests/RadioTile/RadioTile.test.ts b/tests/RadioTile/RadioTile.test.ts
new file mode 100644
index 00000000..351c01dc
--- /dev/null
+++ b/tests/RadioTile/RadioTile.test.ts
@@ -0,0 +1,197 @@
+import { render, screen } from "@testing-library/svelte";
+import { user } from "../setup-tests";
+import RadioTile from "./RadioTile.test.svelte";
+import RadioTileCustom from "./RadioTileCustom.test.svelte";
+import RadioTileSingle from "./RadioTile.single.test.svelte";
+import RadioTileGroup from "./RadioTile.group.test.svelte";
+
+describe("RadioTile", () => {
+ it("should render with default props", () => {
+ render(RadioTile);
+
+ const input = screen.getByRole("radio");
+ expect(input).toBeInTheDocument();
+ expect(input).toHaveAttribute("name", "test-group");
+ expect(input).toHaveAttribute("value", "test");
+ expect(input).not.toBeChecked();
+ expect(screen.getByText("Test content")).toBeInTheDocument();
+ expect(screen.getByTitle("Tile checkmark")).toBeInTheDocument();
+ });
+
+ it("should handle checked state", () => {
+ render(RadioTile, {
+ props: { checked: true },
+ });
+
+ const input = screen.getByRole("radio");
+ expect(input).toBeChecked();
+ expect(screen.getByText("Test content").closest(".bx--tile")).toHaveClass(
+ "bx--tile--is-selected",
+ );
+ });
+
+ it("should handle light variant", () => {
+ render(RadioTile, {
+ props: { light: true },
+ });
+
+ expect(screen.getByText("Test content").closest(".bx--tile")).toHaveClass(
+ "bx--tile--light",
+ );
+ });
+
+ it("should handle disabled state", () => {
+ render(RadioTile, {
+ props: { disabled: true },
+ });
+
+ const input = screen.getByRole("radio");
+ expect(input).toBeDisabled();
+ expect(screen.getByText("Test content").closest(".bx--tile")).toHaveClass(
+ "bx--tile--disabled",
+ );
+ });
+
+ it("should handle required state", () => {
+ render(RadioTile, {
+ props: { required: true },
+ });
+
+ expect(screen.getByRole("radio")).toHaveAttribute("required");
+ });
+
+ it("should handle custom value", () => {
+ render(RadioTile, {
+ props: { value: "custom-value" },
+ });
+
+ expect(screen.getByRole("radio")).toHaveAttribute("value", "custom-value");
+ });
+
+ it("should handle custom tabindex", () => {
+ render(RadioTile, {
+ props: { tabindex: "1" },
+ });
+
+ expect(screen.getByRole("radio")).toHaveAttribute("tabindex", "1");
+ });
+
+ it("should handle custom icon description", () => {
+ render(RadioTile, {
+ props: { iconDescription: "Custom checkmark" },
+ });
+
+ expect(screen.getByTitle("Custom checkmark")).toBeInTheDocument();
+ });
+
+ it("should handle custom id", () => {
+ render(RadioTile, { props: { id: "custom-id" } });
+
+ expect(screen.getByRole("radio")).toHaveAttribute("id", "custom-id");
+
+ const radioTileLabel = screen.getByText("Test content").closest("label");
+ assert(radioTileLabel);
+ expect(radioTileLabel).toHaveAttribute("for", "custom-id");
+ });
+
+ // TODO(bug): support standalone radio tile.
+ it.skip("should handle custom name", () => {
+ render(RadioTileSingle);
+
+ expect(screen.getByRole("radio")).toHaveAttribute("name", "custom-name");
+ });
+
+ it("should handle custom slots", () => {
+ render(RadioTileCustom);
+
+ expect(screen.getByText("Custom content")).toBeInTheDocument();
+ });
+
+ it("should handle change event", async () => {
+ const consoleLog = vi.spyOn(console, "log");
+ render(RadioTile);
+
+ const input = screen.getByRole("radio");
+ await user.click(input);
+
+ expect(input).toBeChecked();
+ expect(consoleLog).toHaveBeenCalledWith("change");
+ });
+
+ it("should handle keyboard events", async () => {
+ render(RadioTileGroup);
+
+ const inputs = screen.getAllByRole("radio");
+
+ expect(inputs[1]).not.toHaveFocus();
+ expect(inputs[1]).toBeChecked();
+
+ await user.tab();
+ expect(inputs[1]).toHaveFocus();
+
+ await user.keyboard("{ArrowDown}");
+ expect(inputs[2]).toHaveFocus();
+ expect(inputs[2]).toBeChecked();
+
+ await user.keyboard("{ArrowDown}");
+ expect(inputs[0]).toHaveFocus();
+ expect(inputs[0]).toBeChecked();
+ });
+
+ it("supports programmatic selection", async () => {
+ render(RadioTileGroup);
+
+ const inputs = screen.getAllByRole("radio");
+ expect(inputs[1]).not.toHaveFocus();
+ expect(inputs[1]).toBeChecked();
+ expect(screen.getByText(/Selected: Standard plan/)).toBeInTheDocument();
+
+ await user.click(inputs[2]);
+ expect(inputs[2]).toHaveFocus();
+ expect(inputs[2]).toBeChecked();
+ expect(screen.getByText(/Selected: Plus plan/)).toBeInTheDocument();
+
+ await user.click(screen.getByRole("button"));
+ expect(inputs[1]).not.toHaveFocus();
+ expect(inputs[1]).toBeChecked();
+ expect(screen.getByText(/Selected: Standard plan/)).toBeInTheDocument();
+ });
+
+ it("should handle disabled state with events", async () => {
+ render(RadioTile, {
+ props: { disabled: true },
+ });
+
+ const input = screen.getByRole("radio");
+ await user.click(input);
+ expect(input).not.toBeChecked();
+ });
+
+ it("should handle mouse events", async () => {
+ render(RadioTile);
+
+ const tile = screen.getByText("Test content").closest(".bx--tile");
+ assert(tile);
+ await user.hover(tile);
+ await user.unhover(tile);
+ });
+
+ it("should handle custom content slot", () => {
+ render(RadioTileCustom);
+
+ const content = screen.getByText("Custom content");
+ expect(content).toBeInTheDocument();
+ expect(content.tagName).toBe("DIV");
+ });
+
+ it("should handle TileGroup context", () => {
+ render(RadioTile, { props: { checked: true } });
+
+ const input = screen.getByRole("radio");
+ expect(input).toBeChecked();
+ expect(screen.getByText("Test content").closest(".bx--tile")).toHaveClass(
+ "bx--tile--is-selected",
+ );
+ expect(input).toHaveAttribute("name", "test-group");
+ });
+});
diff --git a/tests/RadioTile/RadioTileCustom.test.svelte b/tests/RadioTile/RadioTileCustom.test.svelte
new file mode 100644
index 00000000..9d97ddf9
--- /dev/null
+++ b/tests/RadioTile/RadioTileCustom.test.svelte
@@ -0,0 +1,9 @@
+
+
+
+
+ Custom content
+
+