Building Accessible and Good-Looking Tab Components in React

Introduction

Tabs are a popular UI pattern that helps save screen space by organizing content into categorized sections. As a frontend developer, it’s essential to know how to implement tabs not only from a coding perspective but also to enhance user experience (UX). In this article, we’ll explore how to build an accessible and visually appealing tab component in React from scratch without using additional packages.

Planning the Tab Component Structure

When designing a tab component, we need to consider the wrapper element that contains the component. Our tab component requires a navigation area where tabs are aligned horizontally or vertically using an unordered list. This approach is excellent from a semantic perspective and ensures accessibility for both general and assistive uses.

Creating a React Project

To create a React project, you can use various methods such as using Create React App (CRA), Vite, or installing React and React DOM directly without any wrapper. For this tutorial, we’ll use Vite to create a TypeScript-based React app. Run the following command in your terminal:

npx degit vitejs/vite-react-ts react-tabs

Customizing the Project Structure

Let’s clean up the project by removing the Vite-React template boilerplate. We’ll also create a new subdirectory inside the src directory named components and add a subdirectory named Tabs to house our tab component and its counterparts.

Defining Types for Our Components

Next, we’ll declare prop types for the components we’ll be adding later. We’ll create a TypeScript file in the types folder to contain the types for both components. The TabItem component represents an element containing the content associated with the tab, while the TabList component represents a list of TabItem components.

Handling IDs

To ensure accessibility, we’ll use ARIA attributes that depend on the value of the ID attributes of certain elements. Instead of relying on an additional package to generate dynamic IDs, we’ll use the label value of each TabItem to formulate ID values.

Creating the TabItem Component

The TabItem component represents the content of a tab in the TabList. It accepts and uses a label and HTML nodes as props to construct a container or panel for tab content. We’ll assign the tabpanel role to the tab content and utilize the aria-labelledby attribute to link it to the triggering button.

Creating the TabList Component

The TabList component serves as a parent to one or more TabItem components. It uses two key props: one for the selected tab’s index and another for its child nodes. We’ll use the useState Hook to maintain the currently selected tab’s index and loop through the tabs array to populate a navigation area with trigger points that reveal the corresponding tab content.

Implementing the Components

We’ll use both the TabList and TabItem components together to implement a tabbed UI in our app. Here’s an example demonstrating how to use these components in App.tsx:

“`jsx
import React from ‘eact’;
import { TabList, TabItem } from ‘./components/Tabs’;

function App() {
return (


Tab 1 content
Tab 2 content
Tab 3 content

);
}

export default App;
“`

Styling the Components

To enhance the visual appeal and functionality of the tab components, we need to apply some styling to what we have created so far. We’ll reset the default browser styles, tweak the App container, and add tab-specific styles using CSS classes.

Using React Bootstrap to Style Tab Components

Alternatively, we can use React Bootstrap to style our tab components. We’ll modify the button and navigation styles in the TabList component and utilize container components provided by Bootstrap. We’ll also add Bootstrap transitions to enhance the user experience.

By following this tutorial, you’ve learned how to build an accessible and good-looking tab component in React from scratch without using additional packages. You can experiment with the code, add your own personal touch and style, and share your thoughts in the comment section below.

Leave a Reply

Your email address will not be published. Required fields are marked *