Tabs Component
Relevant source files
The following files were used as context for generating this wiki page:
The Tabs Component is a navigation overlay element within the @pcstyle/ui library designed to facilitate switching between different views or content panes. It is built as a functional React component that integrates deeply with the library's dual-theme system, supporting both "cyber" and "minimal" visual styles.
The component utilizes framer-motion for layout animations, specifically for the active tab indicator, ensuring smooth transitions when a user interacts with the navigation items. It is exported as part of the core component library, allowing it to be used alongside other layout and feedback elements.
Sources: src/components/overlays/Tabs.tsx:1-45, src/index.ts:1-14, package.json:23-28
Architecture and Design
The Tabs component is architected as a controlled component, meaning its state (the active tab) is managed by the parent component and passed down via props. It consumes global theme state from the UIProvider to determine its aesthetic presentation.
Component Structure
The component is composed of a container div acting as a flexbox row with a bottom border. Each tab is rendered as a button containing a label and an optional motion.div for the active indicator.
The diagram above shows the data flow from the UIProvider and Parent component into the Tabs structure.
Sources: src/components/overlays/Tabs.tsx:14-43, src/provider/index.tsx:39-47
Theme Integration
The Tabs component dynamically adjusts its styling based on the theme value retrieved from the useUI hook. The library supports two primary modes: cyber and minimal.
| Theme Mode | Active Text Color | Border Color | Active Indicator Style |
|---|---|---|---|
| cyber | #ff00ff (Neon Pink) | border-[#ff00ff]/20 | bg-[#ff00ff] + shadow glow |
| minimal | text-black | border-zinc-100 | bg-black |
Sources: src/components/overlays/Tabs.tsx:18-38, src/theme/colors.ts:8-35
Component Properties (Props)
The TabsProps interface defines the expected input for the component, ensuring strict type safety as mandated by the project's tsconfig.json and cubic.yaml rules.
| Property | Type | Description |
|---|---|---|
tabs | { id: string; label: string }[] | An array of objects defining the available tab navigation items. |
activeTab | string | The ID of the currently selected tab. |
onTabChange | (id: string) => void | Callback function triggered when a user clicks a tab. |
className | string (optional) | Additional CSS classes to apply to the container. |
Sources: src/components/overlays/Tabs.tsx:8-13, tsconfig.json:11, cubic.yaml:18-21
Logic and State Flow
The interaction flow follows a standard React pattern where user input triggers an event that propagates to the parent to update the state, which then re-renders the component with a new activeTab.
The sequence diagram illustrates the loop between user interaction and state updates that trigger the visual transition.
Sources: src/components/overlays/Tabs.tsx:24-38, src/provider/index.tsx:23-37
Implementation Details
Typography and Spacing
The component adheres to the design tokens defined in the system. It uses uppercase text, tracking-widest letter spacing (0.4em), and font-black (weight 900) for tab labels. Font sizes are responsive, shifting from text-[10px] on mobile to text-xs (0.75rem) on medium devices.
Sources: src/components/overlays/Tabs.tsx:28, src/theme/tokens.ts:11-30
Animation Logic
The active indicator uses a motion.div from the framer-motion library. By using the layoutId="activeTab", the indicator performs a shared element transition, sliding smoothly between buttons as the activeTab prop changes.
{isActive && (
<motion.div
layoutId="activeTab"
className={`absolute bottom-0 left-0 right-0 h-[2px] ${isCyber ? "bg-[#ff00ff] shadow-[0_0_10px_#ff00ff]" : "bg-black"}`}
/>
)}
Sources: src/components/overlays/Tabs.tsx:32-37, package.json:34
Summary
The Tabs Component serves as a highly stylized navigation utility that leverages React context and Framer Motion to provide a theme-aware user experience. It encapsulates the project's design philosophy by offering a stark contrast between high-glow "cyber" aesthetics and clean "minimal" lines, while maintaining a consistent API for developers.