Installation
Usage
import { DragAndDropTabs } from "@/components/ruixen/drag-and-drop-tabs";
export default function App() {
return (
<DragAndDropTabs
items={[
{ value: "tab1", label: "Tab 1", content: "Content for Tab 1." },
{ value: "tab2", label: "Tab 2", content: "Content for Tab 2." },
{ value: "tab3", label: "Tab 3", content: "Content for Tab 3." },
]}
defaultValue="tab1"
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | DragTabItem[] | Default tabs | Array of tab configurations |
defaultValue | string | First item | Initially active tab |
onChange | (value: string) => void | - | Callback when active tab changes |
sound | boolean | true | Enable audio ticks on drag events |
className | string | - | Additional CSS classes |
Features
- Spring-Animated Reorder: Transforms driven through
motion/reactsprings instead of CSS transforms - Audio Feedback: Tick sound on drag start, reorder (when
over.idchanges), and drop - Dragging State: Scale up to 1.06 with spring, slight opacity reduction, elevated shadow
- Active Indicator Pill: Spring-animated pill tracks the active tab position
- Staggered Cascade: After reorder, tabs settle with distance-based delay from the drop position —
delay: |index - dropIndex| * 0.025s - Self-Contained: No external UI dependencies, inline styles with CSS variables
Types
interface DragTabItem {
value: string;
label: string;
content?: React.ReactNode;
}
