diff --git a/app/components/ToggleGroup.js b/app/components/ToggleGroup.js
new file mode 100644
index 0000000..08ba1e3
--- /dev/null
+++ b/app/components/ToggleGroup.js
@@ -0,0 +1,137 @@
+import React, { memo, useCallback, useId, forwardRef } from "react";
+
+const ToggleGroup = memo(
+ forwardRef((props, ref) => {
+ const {
+ children,
+ className = "",
+ position = "left",
+ state = "default",
+ showText = true,
+ ariaLabel,
+ onChange,
+ onFocus,
+ onBlur,
+ ...rest
+ } = props;
+
+ const groupId = useId();
+
+ // Position-based styling for border radius
+ const getPositionStyles = useCallback((pos) => {
+ switch (pos) {
+ case "left":
+ return "rounded-l-[var(--measures-radius-medium)] rounded-r-none";
+ case "middle":
+ return "rounded-none";
+ case "right":
+ return "rounded-r-[var(--measures-radius-medium)] rounded-l-none";
+ default:
+ return "rounded-[var(--measures-radius-medium)]";
+ }
+ }, []);
+
+ // State-based styling
+ const getStateStyles = useCallback((state) => {
+ switch (state) {
+ case "hover":
+ return "bg-[var(--color-magenta-magenta100)] text-[var(--color-content-default-primary)]";
+ case "focus":
+ return "bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] shadow-[0_0_5px_1px_#3281F8]";
+ case "selected":
+ return "bg-[var(--color-magenta-magenta100)] text-[var(--color-content-default-primary)] shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]";
+ case "default":
+ default:
+ return "bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)]";
+ }
+ }, []);
+
+ const positionStyles = getPositionStyles(position);
+ const stateStyles = getStateStyles(state);
+
+ const handleClick = useCallback(
+ (e) => {
+ if (onChange) {
+ onChange(e);
+ }
+ },
+ [onChange]
+ );
+
+ const handleFocus = useCallback(
+ (e) => {
+ if (onFocus) {
+ onFocus(e);
+ }
+ },
+ [onFocus]
+ );
+
+ const handleBlur = useCallback(
+ (e) => {
+ if (onBlur) {
+ onBlur(e);
+ }
+ },
+ [onBlur]
+ );
+
+ const handleKeyDown = useCallback(
+ (e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ if (onChange) {
+ onChange(e);
+ }
+ }
+ },
+ [onChange]
+ );
+
+ const toggleClasses = `
+ ${positionStyles}
+ ${stateStyles}
+ py-[var(--measures-spacing-008)]
+ px-[var(--measures-spacing-008)]
+ gap-[var(--measures-spacing-008)]
+ font-inter
+ font-medium
+ text-[12px]
+ leading-[12px]
+ cursor-pointer
+ transition-all
+ duration-200
+ focus:outline-none
+ focus-visible:shadow-[0_0_5px_1px_#3281F8]
+ hover:bg-[var(--color-magenta-magenta100)]
+ flex
+ items-center
+ justify-center
+ ${className}
+ `
+ .trim()
+ .replace(/\s+/g, " ");
+
+ return (
+
+ );
+ })
+);
+
+ToggleGroup.displayName = "ToggleGroup";
+
+export default ToggleGroup;
diff --git a/app/forms/page.js b/app/forms/page.js
index 3453d6c..7b154a5 100644
--- a/app/forms/page.js
+++ b/app/forms/page.js
@@ -1,18 +1,16 @@
"use client";
import React, { useState } from "react";
-import Toggle from "../components/Toggle";
+import ToggleGroup from "../components/ToggleGroup";
export default function FormsPlayground() {
+ const [selectedToggle, setSelectedToggle] = useState("active");
+ const [selectedFilter, setSelectedFilter] = useState("all");
const [toggleStates, setToggleStates] = useState({
default: false,
hover: false,
selected: true,
focus: false,
- disabled: false,
- icon: false,
- text: false,
- both: false,
});
const handleToggleChange = (key) => (e) => {
@@ -22,76 +20,267 @@ export default function FormsPlayground() {
}));
};
+ const handleToggleGroupChange = (position) => (e) => {
+ setSelectedToggle(position);
+ };
+
+ const handleFilterChange = (filter) => (e) => {
+ setSelectedFilter(filter);
+ };
+
return (
Forms Playground
- Toggle Examples
+ Toggle Group Examples
-
States
-
-
-
-
-
-
+
+ Interactive Toggle Group
+
+
+
+ Active Deals
+
+
+ Inactive Deals
+
+
+ Pending Deals
+
-
Content Types
-
-
-
-
+
States
+
+
+ Default
+
+
+ Hover
+
+
+ Focus
+
+
+ Selected
+
+
+
+
+
+
Positions
+
+
+ Left
+
+
+ Middle
+
+
+ Middle
+
+
+ Right
+
+
+
+
+
+
Without Text
+
+
+ Icon
+
+
+ Icon
+
+
+ Icon
+
+
+
+
+
+
+ {/* Content Visibility Examples */}
+
+ Content Visibility Examples
+
+ {/* Deal Management Example */}
+
+
Deal Management
+
+
+ Active Deals
+
+
+ Inactive Deals
+
+
+ Pending Deals
+
+
+
+ {/* Content that changes based on toggle selection */}
+
+ {selectedToggle === "active" && (
+
+
+ Active Deals
+
+
+ -
+ Summer Sale - 50% Off
+ $299
+
+ -
+ Black Friday Special
+ $199
+
+
+
+ )}
+
+ {selectedToggle === "inactive" && (
+
+
+ Inactive Deals
+
+
+ -
+ Holiday Sale - Expired
+ $399
+
+ -
+ Spring Clearance - Ended
+ $149
+
+
+
+ )}
+
+ {selectedToggle === "pending" && (
+
+
+ Pending Deals
+
+
+ -
+ Cyber Monday - Coming Soon
+ $99
+
+ -
+ New Year Sale - Pending
+ $79
+
+
+
+ )}
+
+
+
+ {/* Filter Example */}
+
+
Content Filter
+
+
+ All
+
+
+ Featured
+
+
+ Recent
+
+
+
+
+
+
Featured Article
+
+ This is a featured article that shows when "All" or "Featured"
+ is selected.
+
+
+
+
Recent Post
+
+ This is a recent post that shows when "All" or "Recent" is
+ selected.
+
+
+
+
General Content
+
+ This content only shows when "All" is selected.
+
diff --git a/stories/ToggleGroup.stories.js b/stories/ToggleGroup.stories.js
new file mode 100644
index 0000000..b22af10
--- /dev/null
+++ b/stories/ToggleGroup.stories.js
@@ -0,0 +1,210 @@
+import React from "react";
+import ToggleGroup from "../app/components/ToggleGroup";
+
+export default {
+ title: "Forms/ToggleGroup",
+ component: ToggleGroup,
+ parameters: {
+ layout: "centered",
+ },
+ argTypes: {
+ position: {
+ control: { type: "select" },
+ options: ["left", "middle", "right"],
+ },
+ state: {
+ control: { type: "select" },
+ options: ["default", "hover", "focus", "selected"],
+ },
+ showText: {
+ control: { type: "boolean" },
+ },
+ },
+};
+
+const Template = (args) => Toggle Item;
+
+export const Default = Template.bind({});
+Default.args = {
+ position: "left",
+ state: "default",
+ showText: true,
+};
+
+export const Middle = Template.bind({});
+Middle.args = {
+ position: "middle",
+ state: "default",
+ showText: true,
+};
+
+export const Right = Template.bind({});
+Right.args = {
+ position: "right",
+ state: "default",
+ showText: true,
+};
+
+export const States = () => (
+
+
+
Toggle Group States
+
+
+ Default
+
+
+ Hover
+
+
+ Focus
+
+
+ Selected
+
+
+
+
+);
+
+export const Positions = () => (
+
+
+
Toggle Group Positions
+
+
+ Left
+
+
+ Middle
+
+
+ Middle
+
+
+ Right
+
+
+
+
+);
+
+export const WithText = Template.bind({});
+WithText.args = {
+ position: "left",
+ state: "default",
+ showText: true,
+ children: "Active Deals",
+};
+
+export const WithoutText = Template.bind({});
+WithoutText.args = {
+ position: "left",
+ state: "default",
+ showText: false,
+ children: "☰",
+};
+
+export const WithIcons = () => (
+
+
+
Toggle Group with Icons
+
+
+ ☰
+
+
+ ☰
+
+
+ ☰
+
+
+
+
+);
+
+export const Interactive = () => {
+ const [selectedPosition, setSelectedPosition] = React.useState("left");
+ const [state, setState] = React.useState("default");
+ const [showText, setShowText] = React.useState(true);
+
+ return (
+
+
+
Interactive Toggle Group
+
+ setSelectedPosition("left")}
+ ariaLabel={!showText ? "Active Deals" : undefined}
+ >
+ {showText ? "Active Deals" : "☰"}
+
+ setSelectedPosition("middle")}
+ ariaLabel={!showText ? "Inactive Deals" : undefined}
+ >
+ {showText ? "Inactive Deals" : "☰"}
+
+ setSelectedPosition("right")}
+ ariaLabel={!showText ? "Pending Deals" : undefined}
+ >
+ {showText ? "Pending Deals" : "☰"}
+
+
+
+
+
Controls
+
+
+
+
+
+
+ setShowText(e.target.checked)}
+ />
+
+
+
+
+
+ );
+};
diff --git a/tests/accessibility/ToggleGroup.a11y.test.jsx b/tests/accessibility/ToggleGroup.a11y.test.jsx
new file mode 100644
index 0000000..387b1e3
--- /dev/null
+++ b/tests/accessibility/ToggleGroup.a11y.test.jsx
@@ -0,0 +1,92 @@
+import React from "react";
+import { render, screen, fireEvent } from "@testing-library/react";
+import { describe, it, expect, vi } from "vitest";
+import { axe, toHaveNoViolations } from "jest-axe";
+import ToggleGroup from "../../app/components/ToggleGroup";
+
+expect.extend(toHaveNoViolations);
+
+describe("ToggleGroup Accessibility", () => {
+ it("has proper ARIA attributes", () => {
+ render(Toggle Item);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveAttribute("type", "button");
+ expect(toggleGroup).toHaveAttribute("role", "button");
+ });
+
+ it("has proper ARIA attributes when focused", () => {
+ render(Focused Toggle);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveAttribute("type", "button");
+ expect(toggleGroup).toHaveAttribute("role", "button");
+ });
+
+ it("handles keyboard navigation", () => {
+ const handleChange = vi.fn();
+ render(Keyboard Toggle);
+ const toggleGroup = screen.getByRole("button");
+
+ // Test Enter key
+ fireEvent.keyDown(toggleGroup, { key: "Enter" });
+ expect(handleChange).toHaveBeenCalledTimes(1);
+
+ // Test Space key
+ fireEvent.keyDown(toggleGroup, { key: " " });
+ expect(handleChange).toHaveBeenCalledTimes(2);
+ });
+
+ it("handles focus state accessibility", () => {
+ render(Focus Toggle);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("shadow-[0_0_5px_1px_#3281F8]");
+ });
+
+ it("handles selected state accessibility", () => {
+ render(Selected Toggle);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("bg-[var(--color-magenta-magenta100)]");
+ expect(toggleGroup).toHaveClass(
+ "shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]"
+ );
+ });
+
+ it("has no accessibility violations", async () => {
+ const { container } = render(Accessible Toggle);
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+ });
+
+ it("has no accessibility violations when focused", async () => {
+ const { container } = render(
+ Focused Toggle
+ );
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+ });
+
+ it("has no accessibility violations when selected", async () => {
+ const { container } = render(
+ Selected Toggle
+ );
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+ });
+
+ it("has no accessibility violations with text", async () => {
+ const { container } = render(
+ Text Toggle
+ );
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+ });
+
+ it("has no accessibility violations without text", async () => {
+ const { container } = render(
+
+ Icon Toggle
+
+ );
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+ });
+});
diff --git a/tests/integration/ToggleGroup.integration.test.jsx b/tests/integration/ToggleGroup.integration.test.jsx
new file mode 100644
index 0000000..1802d3c
--- /dev/null
+++ b/tests/integration/ToggleGroup.integration.test.jsx
@@ -0,0 +1,215 @@
+import React, { useState } from "react";
+import { render, screen, fireEvent, waitFor } from "@testing-library/react";
+import { describe, it, expect, vi } from "vitest";
+import ToggleGroup from "../../app/components/ToggleGroup";
+
+// Test component for form integration
+const TestForm = () => {
+ const [selectedToggle, setSelectedToggle] = useState("left");
+
+ return (
+
+ );
+};
+
+// Dynamic component for prop changes
+const DynamicToggleGroup = ({ position, state, showText }) => {
+ return (
+
+ Dynamic Content
+
+ );
+};
+
+describe("ToggleGroup Integration", () => {
+ it("handles form submission", async () => {
+ const handleSubmit = vi.fn();
+ render(
+
+ );
+
+ const submitButton = screen.getByRole("button", { name: "Submit" });
+ fireEvent.click(submitButton);
+ expect(handleSubmit).toHaveBeenCalledTimes(1);
+ });
+
+ it("handles keyboard navigation between toggle groups", () => {
+ render();
+ const toggleGroups = screen.getAllByRole("button");
+
+ // Focus first toggle group
+ toggleGroups[0].focus();
+ expect(toggleGroups[0]).toHaveFocus();
+
+ // Test keyboard navigation
+ fireEvent.keyDown(toggleGroups[0], { key: "Tab" });
+ // Note: Tab navigation behavior depends on browser implementation
+ });
+
+ it("handles dynamic prop changes", () => {
+ const { rerender } = render(
+
+ );
+
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "rounded-l-[var(--measures-radius-medium)]",
+ "rounded-r-none"
+ );
+ expect(toggleGroup).toHaveTextContent("Dynamic Content");
+
+ rerender(
+
+ );
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("rounded-none");
+ expect(toggleGroup).toHaveClass("bg-[var(--color-magenta-magenta100)]");
+ expect(toggleGroup).toHaveTextContent("Dynamic Content");
+ });
+
+ it("handles multiple toggle groups in form", () => {
+ render();
+ const toggleGroups = screen.getAllByRole("button");
+ expect(toggleGroups).toHaveLength(3);
+
+ // Test clicking different toggle groups
+ fireEvent.click(toggleGroups[0]);
+ fireEvent.click(toggleGroups[1]);
+ fireEvent.click(toggleGroups[2]);
+ });
+
+ it("handles state changes", async () => {
+ const { rerender } = render();
+ const toggleGroups = screen.getAllByRole("button");
+
+ // Initially, left should be selected
+ expect(toggleGroups[0]).toHaveClass("bg-[var(--color-magenta-magenta100)]");
+
+ // Click middle toggle
+ fireEvent.click(toggleGroups[1]);
+ await waitFor(() => {
+ expect(toggleGroups[1]).toHaveClass(
+ "bg-[var(--color-magenta-magenta100)]"
+ );
+ });
+ });
+
+ it("handles content changes", () => {
+ const { rerender } = render(
+ Initial Content
+ );
+
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveTextContent("Initial Content");
+
+ rerender(Updated Content);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveTextContent("Updated Content");
+
+ rerender(Hidden Content);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveTextContent("Hidden Content");
+ });
+
+ it("handles performance with many toggle groups", () => {
+ const ManyToggleGroups = () => {
+ const [selected, setSelected] = useState(0);
+
+ return (
+
+ {Array.from({ length: 10 }, (_, i) => (
+ setSelected(i)}
+ >
+ Option {i + 1}
+
+ ))}
+
+ );
+ };
+
+ render();
+ const toggleGroups = screen.getAllByRole("button");
+ expect(toggleGroups).toHaveLength(10);
+
+ // Test clicking different toggle groups
+ fireEvent.click(toggleGroups[5]);
+ expect(toggleGroups[5]).toHaveClass("bg-[var(--color-magenta-magenta100)]");
+ });
+
+ it("handles rapid state changes", async () => {
+ const { rerender } = render();
+ const toggleGroups = screen.getAllByRole("button");
+
+ // Rapidly change states
+ for (let i = 0; i < 5; i++) {
+ fireEvent.click(toggleGroups[i % 3]);
+ await waitFor(() => {
+ expect(toggleGroups[i % 3]).toHaveClass(
+ "bg-[var(--color-magenta-magenta100)]"
+ );
+ });
+ }
+ });
+
+ it("handles mixed content types", () => {
+ render(
+
+
+ Text Only
+
+
+ Icon Only
+
+
+ Text Only
+
+
+ );
+
+ const toggleGroups = screen.getAllByRole("button");
+ expect(toggleGroups[0]).toHaveTextContent("Text Only");
+ expect(toggleGroups[1]).toHaveTextContent("Icon Only");
+ expect(toggleGroups[2]).toHaveTextContent("Text Only");
+ });
+});
diff --git a/tests/unit/ToggleGroup.test.jsx b/tests/unit/ToggleGroup.test.jsx
new file mode 100644
index 0000000..a284398
--- /dev/null
+++ b/tests/unit/ToggleGroup.test.jsx
@@ -0,0 +1,213 @@
+import React from "react";
+import { render, screen, fireEvent } from "@testing-library/react";
+import { describe, it, expect, vi } from "vitest";
+import ToggleGroup from "../../app/components/ToggleGroup";
+
+describe("ToggleGroup Component", () => {
+ it("renders with default props", () => {
+ render(Test Content);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toBeInTheDocument();
+ expect(toggleGroup).toHaveTextContent("Test Content");
+ });
+
+ it("renders with custom props", () => {
+ render(
+
+ Custom Content
+
+ );
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toBeInTheDocument();
+ expect(toggleGroup).toHaveTextContent("Custom Content");
+ });
+
+ it("handles position prop correctly", () => {
+ const { rerender } = render(
+ Left
+ );
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "rounded-l-[var(--measures-radius-medium)]",
+ "rounded-r-none"
+ );
+
+ rerender(Middle);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("rounded-none");
+
+ rerender(Right);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "rounded-r-[var(--measures-radius-medium)]",
+ "rounded-l-none"
+ );
+ });
+
+ it("handles state prop correctly", () => {
+ const { rerender } = render(
+ Default
+ );
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "bg-[var(--color-surface-default-primary)]"
+ );
+
+ rerender(Hover);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("bg-[var(--color-magenta-magenta100)]");
+
+ rerender(Focus);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "bg-[var(--color-surface-default-primary)]",
+ "shadow-[0_0_5px_1px_#3281F8]"
+ );
+
+ rerender(Selected);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "bg-[var(--color-magenta-magenta100)]",
+ "shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]"
+ );
+ });
+
+ it("handles showText prop correctly", () => {
+ const { rerender } = render(
+ Visible Text
+ );
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveTextContent("Visible Text");
+
+ rerender(☰);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveTextContent("☰");
+ });
+
+ it("calls onChange when clicked", () => {
+ const handleChange = vi.fn();
+ render(Clickable);
+ const toggleGroup = screen.getByRole("button");
+
+ fireEvent.click(toggleGroup);
+ expect(handleChange).toHaveBeenCalledTimes(1);
+ });
+
+ it("calls onFocus when focused", () => {
+ const handleFocus = vi.fn();
+ render(Focusable);
+ const toggleGroup = screen.getByRole("button");
+
+ fireEvent.focus(toggleGroup);
+ expect(handleFocus).toHaveBeenCalledTimes(1);
+ });
+
+ it("calls onBlur when blurred", () => {
+ const handleBlur = vi.fn();
+ render(Blurable);
+ const toggleGroup = screen.getByRole("button");
+
+ fireEvent.blur(toggleGroup);
+ expect(handleBlur).toHaveBeenCalledTimes(1);
+ });
+
+ it("handles keyboard events correctly", () => {
+ const handleChange = vi.fn();
+ render(Keyboard);
+ const toggleGroup = screen.getByRole("button");
+
+ // Test Enter key
+ fireEvent.keyDown(toggleGroup, { key: "Enter" });
+ expect(handleChange).toHaveBeenCalledTimes(1);
+
+ // Test Space key
+ fireEvent.keyDown(toggleGroup, { key: " " });
+ expect(handleChange).toHaveBeenCalledTimes(2);
+
+ // Test other key (should not trigger)
+ fireEvent.keyDown(toggleGroup, { key: "Escape" });
+ expect(handleChange).toHaveBeenCalledTimes(2);
+ });
+
+ it("applies correct classes for different states", () => {
+ const { rerender } = render(
+ Default
+ );
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "bg-[var(--color-surface-default-primary)]"
+ );
+
+ rerender(Hover);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("bg-[var(--color-magenta-magenta100)]");
+
+ rerender(Focus);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("shadow-[0_0_5px_1px_#3281F8]");
+
+ rerender(Selected);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "bg-[var(--color-magenta-magenta100)]",
+ "shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]"
+ );
+ });
+
+ it("applies correct position classes", () => {
+ const { rerender } = render(
+ Left
+ );
+ let toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "rounded-l-[var(--measures-radius-medium)]",
+ "rounded-r-none"
+ );
+
+ rerender(Middle);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("rounded-none");
+
+ rerender(Right);
+ toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "rounded-r-[var(--measures-radius-medium)]",
+ "rounded-l-none"
+ );
+ });
+
+ it("applies correct base classes", () => {
+ render(Base);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass(
+ "py-[var(--measures-spacing-008)]",
+ "px-[var(--measures-spacing-008)]",
+ "gap-[var(--measures-spacing-008)]",
+ "font-inter",
+ "font-medium",
+ "text-[12px]",
+ "leading-[12px]",
+ "cursor-pointer",
+ "transition-all",
+ "duration-200",
+ "focus:outline-none",
+ "focus-visible:shadow-[0_0_5px_1px_#3281F8]",
+ "hover:bg-[var(--color-magenta-magenta100)]",
+ "flex",
+ "items-center",
+ "justify-center"
+ );
+ });
+
+ it("forwards ref correctly", () => {
+ const ref = React.createRef();
+ render(Ref Test);
+ expect(ref.current).toBeInstanceOf(HTMLButtonElement);
+ });
+
+ it("applies custom className", () => {
+ render(Custom);
+ const toggleGroup = screen.getByRole("button");
+ expect(toggleGroup).toHaveClass("custom-class");
+ });
+});