diff --git a/src/components/nodes/SettingsTabBar.tsx b/src/components/nodes/SettingsTabBar.tsx new file mode 100644 index 00000000..c4195864 --- /dev/null +++ b/src/components/nodes/SettingsTabBar.tsx @@ -0,0 +1,46 @@ +import React from "react"; + +interface SettingsTabBarProps { + activeTab: "primary" | "fallback"; + onTabChange: (tab: "primary" | "fallback") => void; + primaryLabel: string; + fallbackLabel: string; +} + +export function SettingsTabBar({ + activeTab, + onTabChange, + primaryLabel, + fallbackLabel, +}: SettingsTabBarProps) { + return ( +
+ + +
+ ); +} diff --git a/src/components/nodes/__tests__/SettingsTabBar.test.tsx b/src/components/nodes/__tests__/SettingsTabBar.test.tsx new file mode 100644 index 00000000..c21f08ff --- /dev/null +++ b/src/components/nodes/__tests__/SettingsTabBar.test.tsx @@ -0,0 +1,67 @@ +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import { SettingsTabBar } from "../SettingsTabBar"; + +describe("SettingsTabBar", () => { + it("renders both tab labels", () => { + render( + + ); + + expect(screen.getByText("Nano Banana")).toBeInTheDocument(); + expect(screen.getByText("Flux Dev")).toBeInTheDocument(); + }); + + it("highlights active tab", () => { + render( + + ); + + const primaryTab = screen.getByText("Nano Banana"); + const fallbackTab = screen.getByText("Flux Dev"); + + // Active tab should have bg-neutral-700 class + expect(primaryTab.className).toContain("bg-neutral-700"); + expect(fallbackTab.className).not.toContain("bg-neutral-700"); + }); + + it("calls onTabChange when clicking inactive tab", () => { + const onTabChange = vi.fn(); + render( + + ); + + fireEvent.click(screen.getByText("Flux Dev")); + expect(onTabChange).toHaveBeenCalledWith("fallback"); + }); + + it("does not call onTabChange when clicking active tab", () => { + const onTabChange = vi.fn(); + render( + + ); + + fireEvent.click(screen.getByText("Nano Banana")); + expect(onTabChange).not.toHaveBeenCalled(); + }); +});