Skip to main content

ExpandableSection

The ExpandableSection component is a flexible, responsive collapsible section with support for custom icons, additional content, controlled and uncontrolled open state, and fully customizable styling.

import { ExpandableSection } from "tawuniya";

👉 View in Storybook


PropTypeDefaultDescription
iconReact.ReactNode | string—Icon displayed on the left side of the title. Can be a string (icon name) or ReactNode component.
titlestring—The main heading text of the section.
descriptionstring (optional)—Additional text displayed below the title.
contentReact.ReactNode—Content to show when the section is expanded.
additionalReact.ReactNode (optional)—Optional content displayed next to the title, typically for extra actions or info. Shown on desktop, moved/hidden on mobile.
toggleIconReact.ReactNode | string (optional)"arrow-top-b&w"Icon for the toggle button. Can be string (icon name) or ReactNode.
openboolean (optional)—Controls open state externally (controlled mode).
onToggle() => void (optional)—Callback triggered when the toggle button is clicked.
classNamesPartial<{ itemClassName, titleClassName, descriptionClassName, iconClassName, toggleIconClassName }>—Custom class names for styling different parts of the component.

Basic ExpandableSection (uncontrolled)​

<ExpandableSection
icon="network"
title="Basic Section"
description="This is an uncontrolled expandable section"
content={<div>Here is the expandable content</div>}
/>

Controlled ExpandableSection​

const [isOpen, setIsOpen] = useState(true);

<ExpandableSection
icon="network"
title="Controlled Section"
open={isOpen}
onToggle={() => setIsOpen((prev) => !prev)}
content={<div>Controlled content</div>}
/>;

With Additional Content​

<ExpandableSection
icon="network"
title="Section with Additional Content"
additional={<div className="text-sm text-muted-foreground">Extra info</div>}
content={<div>Content goes here</div>}
/>

Custom Toggle Icon​

<ExpandableSection
icon="network"
title="Custom Toggle Icon"
toggleIcon="arrow-top-b&w"
content={<div>Content goes here</div>}
/>

Custom Class Names​

<ExpandableSection
icon="network"
title="Custom Class Names"
classNames={{
itemClassName: "bg-blue-50 border border-blue-200",
titleClassName: "text-blue-700",
descriptionClassName: "text-blue-500",
iconClassName: "text-blue-600",
toggleIconClassName: "text-blue-800",
}}
content={<div>Styled content</div>}
/>

Features​

  • Controlled & Uncontrolled Modes: Works either with external open prop (controlled) or internal state (uncontrolled), giving flexibility in usage.

  • Customizable Icons: Supports icon as a string (icon name) or any ReactNode for both the main icon and toggle button.

  • Additional Content: Allows extra elements (buttons, labels, info) next to the title, displayed differently on desktop and mobile.

  • Responsive Layout: Automatically adjusts layout for mobile screens using useMobile hook.

  • Custom Styling: Fully customizable via classNames prop for title, description, icon, toggle button, and item wrapper.