Create Custom React Accordion
Accordion

Create Custom React Accordion

This React component, Accordian, is an advanced version of an accordion UI element with added features like single and multiple item selection modes. It allows the user to toggle between these modes using a switch. Let’s break down the code to understand how it works.

Overview

  • The Accordian component is a versatile accordion UI that allows for both single and multiple item selection modes.
  • Users can switch between modes using a toggle switch.
  • When in single selection mode, only one accordion item can be expanded at a time.
  • When in multiple selection mode, multiple items can be expanded simultaneously.

Code Breakdown

"use client";

import React, { useState } from "react";
import data from "./data";        

Explanation:

  • "use client" :A directive to ensure the component is rendered on the client side.
  • import React, { useState } from "react";:Imports React and the useState hook for managing state.
  • import data from "./data";:Imports a dataset from a local data file, which is an array of questions and answers.

Component State

const [selected, setSelected] = useState(null);
const [isOn, setIsOn] = useState(false);
const [multiple, setMultiple] = useState([]);        

Explanation:

  • selected: Tracks the currently selected item in single selection mode.
  • isOn: Controls whether multiple selection mode is enabled (true) or disabled (false).
  • multiple: An array that holds the IDs of the items that are currently expanded in multiple selection mode.

Single Selection Handling

const handleSingleSelection = (getCurrentId) => {
  setSelected(getCurrentId === selected ? null : getCurrentId);
};        

Explanation:

  • handleSingleSelection is responsible for toggling the selected state in single selection mode.
  • If the clicked item is already selected, it collapses it by setting selected to null.
  • Otherwise, it sets selected to the clicked item’s id.

Multiple Selection Handling

const toggleSwitch = (getCurrentId) => {
  let copyMultile = [...multiple];
  const findIndexOfCurrentId = copyMultile.indexOf(getCurrentId);

  if (findIndexOfCurrentId === -1) copyMultile.push(getCurrentId);
  else copyMultile.splice(findIndexOfCurrentId, 1);
  setMultiple(copyMultile);
};
        

Explanation:

  • toggleSwitch is used to handle toggling items in multiple selection mode.
  • Steps:Creates a copy of the multiple array.Checks if the clicked item’s id is already in the array (findIndexOfCurrentId).If the id is not in the array (findIndexOfCurrentId === -1), it adds the id to the array.If the id is already in the array, it removes the id from the array.Finally, updates the multiple state with the modified array.

Rendering the UI

return (
  <div className="flex flex-col justify-center w-full p-4">
    <h3 className="font-bold text-lg">Accordion</h3>
    <div className="flex justify-between items-center">
      Enable multiselections
      <button
        className={`flex items-center cursor-pointer w-20 h-10 rounded-full p-1 ${
          isOn ? "bg-green-500" : "bg-gray-300"
        }`}
        onClick={() => setIsOn(!isOn)}
      >
        <div
          className={`flex justify-center items-center bg-white w-8 h-8 rounded-full shadow-md transform transition-transform ${
            isOn ? "translate-x-10" : "translate-x-0"
          }`}
        >
          <span className="text-sm font-semibold">{isOn ? "ON" : "OFF"}</span>
        </div>
      </button>
    </div>

    <div className="pt-4">
      {data && data.length > 0 ? (
        data.map((dataItem) => (
          <div key={dataItem.id} className="w-full">
            <div
              onClick={
                isOn
                  ? () => toggleSwitch(dataItem.id)
                  : () => handleSingleSelection(dataItem.id)
              }
              className="flex justify-between gap-4 bg-slate-400 p-4 cursor-pointer border-b-2"
            >
              <h3>{dataItem.question}</h3>
              {isOn ? (
                multiple.indexOf(dataItem.id) !== -1 ? (
                  <span>-</span>
                ) : (
                  <span>+</span>
                )
              ) : selected === dataItem.id ? (
                <span>-</span>
              ) : (
                <span>+</span>
              )}
            </div>

            {isOn
              ? multiple.indexOf(dataItem.id) !== -1 && (
                  <div className=" p-4 bg-orange-100">{dataItem.answer}</div>
                )
              : selected === dataItem.id && (
                  <div className=" p-4 bg-orange-100">{dataItem.answer}</div>
                )}
          </div>
        ))
      ) : (
        <div> No Data Found!</div>
      )}
    </div>
  </div>
);
        

Explanation:

Wrapper div:

  • Contains the entire accordion UI with some padding and alignment styling.

Title and Toggle Switch:

  • Displays the accordion title (Accordion).
  • A toggle switch is used to enable or disable multiple selection mode.
  • Button Styling

  • Changes the background color based on isOn.
  • Animates the switch handle between "ON" and "OFF" positions.
  • Displays "ON" or "OFF" text depending on the state of isOn.

Rendering Accordion Items:

  • If data is available, it maps through each item and renders it.
  • Item Header:onClick handles the click event based on the current mode (isOn state).The question text is displayed along with a + or - sign to indicate collapsed or expanded state
  • Item Content:

  • Conditionally renders the answer based on the state (selected or multiple).
  • The answer is displayed inside a div with padding and background styling.
  • Conditional Rendering:

  • If isOn is true, multiple items can be expanded, controlled by the multiple array.
  • If isOn is false, only one item can be expanded at a time, controlled by the selected state.
  • Fallback for No Data: If data is not found or is empty, it displays a "No Data Found!" message.


Summary

Single vs Multiple Selection:

  • The component allows toggling between single and multiple item selection modes using a switch.
  • In single selection mode, only one item can be expanded at a time.
  • In multiple selection mode, multiple items can be expanded simultaneously.

State Management:

  • selected handles the state in single selection mode.
  • multiple handles the state in multiple selection mode.
  • isOn toggles between these modes.

Responsive UI:

The component is styled using utility classes (likely from Tailwind CSS), ensuring it is responsive and visually appealing.

This component provides a flexible and interactive way to present content that can be expanded and collapsed, with the added functionality of switching between single and multiple selection modes.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了