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;
}