In modern web applications, enhancing user interaction with a smooth and functional tabbed interface is essential. Whether you’re working on a dashboard, settings page, or even a content management system, having a clean tab switcher enhances user experience.
In this blog, I’ll show you how to create a simple tab switcher in React using styled-components with a “client-first” approach.
The Tab Switcher Component
We’ll build a simple tab switcher with three tabs, each having its own content. Let’s break down the code and understand how it all comes together.
Step 1: Define the Tabs Layout
Let’s define the MainWrapper, TabList, and Tab styled-components for layout and styling.
Tabs.jsx
import styled from 'styled-components'; const MainWrapper = styled.div` display: flex; flex-direction: column; width: 600px; margin: 20px auto; `; const TabList = styled.div` display: flex; cursor: pointer; `; const Tab = styled.div` flex: 1; padding: 10px 20px; background-color: ${(props) => (props.active ? '#007bff' : '#f1f1f1')}; color: ${(props) => (props.active ? '#fff' : '#000')}; text-align: center; border-radius: 5px 5px 0 0; transition: background-color 0.3s ease; font-size: 16px; font-weight: bold; &:not(:last-child) { margin-right: 2px; } `;
- MainWrapper: This centers the tab switcher horizontally and gives it a set width of 600px.
- TabList: This ensures the tabs are laid out horizontally using flexbox.
- Tab: Each tab changes its background and text color based on whether it’s active or not.
Step 2: Tab Content Component
Below the Tab styling, we define the area where content will be displayed when each tab is clicked. This uses simple conditional rendering to show different content for each tab.
const TabContent = styled.div` padding: 20px; border: 1px solid #ddd; border-radius: 0 5px 5px 5px; background-color: #f9f9f9; font-size: 16px; font-weight: 400; `;
Step 3: Managing Active Tabs with useState
In the Tabs functional component, we use the useState hook to track the active tab.
import React, { useState } from 'react'; const Tabs = () => { const [activeTab, setActiveTab] = useState(1); return ( <MainWrapper> <TabList> <Tab active={activeTab === 1} onClick={() => setActiveTab(1)}> Tab 1 </Tab> <Tab active={activeTab === 2} onClick={() => setActiveTab(2)}> Tab 2 </Tab> <Tab active={activeTab === 3} onClick={() => setActiveTab(3)}> Tab 3 </Tab> </TabList> <TabContent> {activeTab === 1 && ( <div> This is content for Tab 1. <br /> <br /> Lorem Ipsum is simply dummy ... </div> )} {activeTab === 2 && ( <div> This is content for Tab 2. <br /> <br /> Lorem Ipsum is simply dummy ... </div> )} {activeTab === 3 && ( <div> This is content for Tab 3. <br /> <br /> Lorem Ipsum is simply dummy ... </div> )} </TabContent> </MainWrapper> ); }; export default Tabs;
Full Code:
Tabs.jsx
import React, { useState } from 'react'; import styled from 'styled-components'; const MainWrapper = styled.div` display: flex; flex-direction: column; width: 600px; margin: 20px auto; `; const TabList = styled.div` display: flex; cursor: pointer; `; const Tab = styled.div` flex: 1; padding: 10px 20px; background-color: ${(props) => (props.active ? '#007bff' : '#f1f1f1')}; color: ${(props) => (props.active ? '#fff' : '#000')}; text-align: center; border-radius: 5px 5px 0 0; transition: background-color 0.3s ease; font-size: 16px; font-weight: bold; &:not(:last-child) { margin-right: 2px; } `; const TabContent = styled.div` padding: 20px; border: 1px solid #ddd; border-radius: 0 5px 5px 5px; background-color: #f9f9f9; font-size: 16px; font-weight: 400; `; const Tabs = () => { const [activeTab, setActiveTab] = useState(1); return ( <MainWrapper> <TabList> <Tab active={activeTab === 1} onClick={() => setActiveTab(1)}> Tab 1 </Tab> <Tab active={activeTab === 2} onClick={() => setActiveTab(2)}> Tab 2 </Tab> <Tab active={activeTab === 3} onClick={() => setActiveTab(3)}> Tab 3 </Tab> </TabList> <TabContent> {activeTab === 1 && ( <div> This is content for Tab 1. <br /> <br /> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. </div> )} {activeTab === 2 && ( <div> This is content for Tab 2. <br /> <br /> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. </div> )} {activeTab === 3 && ( <div> This is content for Tab 3. <br /> <br /> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. </div> )} </TabContent> </MainWrapper> ); }; export default Tabs;
- useState: We use this hook to control which tab is active. Based on the
activeTab
state, we conditionally render the appropriate tab content. - onClick Handler: The
onClick
event handler on each tab switches theactiveTab
when clicked. - Active Styling: The
active
prop passed to the Tab styled-component changes its background and text color based on which tab is active.
Step 5: Rendering the Tabs
To render the Tabs component, simply import it and use it in your app:
App.jsx
import Tabs from './Tabs'; function App() { return ( <> <h1> <Tabs/> </h1> </> ); } export default App;
Output:
Conclusion
Creating a tab switcher in React using styled-components is straightforward. This approach helps you build a reusable, maintainable UI component.
With React’s component-based structure and styled-components’ scoped styles, you can easily extend this example to add more complex features, such as adding icons, lazy-loading tab content, or even nested tab structures.
Feel free to experiment with this code and modify it to fit your project needs!
Happy coding!
Add comment