Tab Selector
Create a component with multiple tabs for users to click through. Display different content as each tab is selected.
Solution
- One
- Two
- Three
Explanation
The HTML Structure
The tabs are stored in an unordered list. Each list item has an onClick function and a dynamic class name.
The content is handled through an object lookup.
The activeTab state
The activeTab value is stored in state and is set via the clickHandler function.
The clickHandler function
When a tab is clicked, it's name is set in state.
Conditional styling for tabs
Each list item shares basic styles and the active style is added conditionally based on the value of activeTab.
The dynamic content
For speed and reduced complexity, the content for each tab is stored in an object. In the section element, content[activeTab] uses the activeTab as the object key to return the correct content.
Code
import { useState } from "react";
import styles from "./Solution.module.css";
const Solution = () => {
type tabProps = "One" | "Two" | "Three";
const [activeTab, setActiveTab] = useState<tabProps>("One");
const clickHandler = (tab: tabProps) => {
setActiveTab(tab);
};
return (
<div>
<ul className={styles.list}>
<li
onClick={() => clickHandler("One")}
className={`${styles.listItem} ${
activeTab === "One" ? styles.active : ""
}`}
>
One
</li>
<li
onClick={() => clickHandler("Two")}
className={`${styles.listItem} ${
activeTab === "Two" ? styles.active : ""
}`}
>
Two
</li>
<li
onClick={() => clickHandler("Three")}
className={`${styles.listItem} ${
activeTab === "Three" ? styles.active : ""
}`}
>
Three
</li>
</ul>
<section className={styles.content}>{content[activeTab]}</section>
</div>
);
};
export default Solution;
const content: { [key: string]: string } = {
One: "This is the first section.",
Two: "This is the second section.",
Three: "This is the third section.",
};
Styling
.list {
display: flex;
gap: 5px;
}
.listItem {
padding: 5px;
border: 1px solid grey;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.listItem:hover,
.listItem:active {
background-color: rgb(212, 179, 135);
color: black;
}
.active {
background-color: rgb(71, 169, 114);
color: white;
}
.content {
margin-top: 20px;
}