Skip to main content

A collapsible content panel for organizing information in a compact space

Import

import { Accordion } from "heroui-solid";

Usage

import {
  ArrowsRotateLeft,
  Box,
  ChevronDown,
  CreditCard,
  PlanetEarth,
  Receipt,
  ShoppingBag
} from "gravity-icons-solid"
import { Accordion } from "heroui-solid"
import { For, type JSX } from "solid-js"

const items: Array<{ content: string; icon: JSX.Element; title: string }> = [
  {
    content:
      "Browse our products, add items to your cart, and proceed to checkout. You'll need to provide shipping and payment information to complete your purchase.",
    icon: <ShoppingBag />,
    title: "How do I place an order?"
  },
  {
    content:
      "Yes, you can modify or cancel your order before it's shipped. Once your order is processed, you can't make changes.",
    icon: <Receipt />,
    title: "Can I modify or cancel my order?"
  },
  {
    content:
      "We accept all major credit cards, including Visa, Mastercard, and American Express.",
    icon: <CreditCard />,
    title: "What payment methods do you accept?"
  },
  {
    content:
      "Shipping costs vary based on your location and the size of your order. We offer free shipping for orders over $50.",
    icon: <Box />,
    title: "How much does shipping cost?"
  },
  {
    content:
      "Yes, we ship to most countries. Please check our shipping rates and policies for more information.",
    icon: <PlanetEarth />,
    title: "Do you ship internationally?"
  },
  {
    content:
      "If you're not satisfied with your purchase, you can request a refund within 30 days of purchase. Please contact our customer support team for assistance.",
    icon: <ArrowsRotateLeft />,
    title: "How do I request a refund?"
  }
]

export function Basic() {
  return (
    <Accordion class="w-full max-w-md">
      <For each={items}>
        {(item) => (
          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                {item.icon ? (
                  <span class="mr-3 size-4 shrink-0 text-muted">
                    {item.icon}
                  </span>
                ) : null}
                {item.title}
                <Accordion.Indicator>
                  <ChevronDown />
                </Accordion.Indicator>
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>{item.content}</Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>
        )}
      </For>
    </Accordion>
  )
}

Anatomy

Import the Accordion component and access all parts using dot notation.

import { Accordion } from "heroui-solid";

export default () => (
  <Accordion>
    <Accordion.Item>
      <Accordion.Heading>
        <Accordion.Trigger>
          <Accordion.Indicator />
        </Accordion.Trigger>
      </Accordion.Heading>
      <Accordion.Panel>
        <Accordion.Body />
      </Accordion.Panel>
    </Accordion.Item>
  </Accordion>
);

Surface

import {
  ArrowsRotateLeft,
  Box,
  ChevronDown,
  CreditCard,
  PlanetEarth,
  Receipt,
  ShoppingBag
} from "gravity-icons-solid"
import { Accordion } from "heroui-solid"
import { For, type JSX } from "solid-js"

const items: Array<{ content: string; icon: JSX.Element; title: string }> = [
  {
    content:
      "Browse our products, add items to your cart, and proceed to checkout. You'll need to provide shipping and payment information to complete your purchase.",
    icon: <ShoppingBag />,
    title: "How do I place an order?"
  },
  {
    content:
      "Yes, you can modify or cancel your order before it's shipped. Once your order is processed, you can't make changes.",
    icon: <Receipt />,
    title: "Can I modify or cancel my order?"
  },
  {
    content:
      "We accept all major credit cards, including Visa, Mastercard, and American Express.",
    icon: <CreditCard />,
    title: "What payment methods do you accept?"
  },
  {
    content:
      "Shipping costs vary based on your location and the size of your order. We offer free shipping for orders over $50.",
    icon: <Box />,
    title: "How much does shipping cost?"
  },
  {
    content:
      "Yes, we ship to most countries. Please check our shipping rates and policies for more information.",
    icon: <PlanetEarth />,
    title: "Do you ship internationally?"
  },
  {
    content:
      "If you're not satisfied with your purchase, you can request a refund within 30 days of purchase. Please contact our customer support team for assistance.",
    icon: <ArrowsRotateLeft />,
    title: "How do I request a refund?"
  }
]

export function Surface() {
  return (
    <Accordion class="w-full max-w-md" variant="surface">
      <For each={items}>
        {(item) => (
          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                {item.icon ? (
                  <span class="mr-3 size-4 shrink-0 text-muted">
                    {item.icon}
                  </span>
                ) : null}
                {item.title}
                <Accordion.Indicator>
                  <ChevronDown />
                </Accordion.Indicator>
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>{item.content}</Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>
        )}
      </For>
    </Accordion>
  )
}

Multiple Expanded

import { Accordion } from "heroui-solid"

export function Multiple() {
  return (
    <Accordion allowsMultipleExpanded class="w-full max-w-md">
      <Accordion.Item>
        <Accordion.Heading>
          <Accordion.Trigger>
            Getting Started
            <Accordion.Indicator />
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            Learn the basics of HeroUI and how to integrate it into your React
            project. This section covers installation, setup, and your first
            component.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>

      <Accordion.Item>
        <Accordion.Heading>
          <Accordion.Trigger>
            Core Concepts
            <Accordion.Indicator />
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            Understand the fundamental concepts behind HeroUI, including the
            compound component pattern, styling with Tailwind CSS, and
            accessibility features.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>

      <Accordion.Item>
        <Accordion.Heading>
          <Accordion.Trigger>
            Advanced Usage
            <Accordion.Indicator />
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            Explore advanced features like custom variants, theme customization,
            and integration with other libraries in your React ecosystem.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>

      <Accordion.Item>
        <Accordion.Heading>
          <Accordion.Trigger>
            Best Practices
            <Accordion.Indicator />
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            Follow our recommended best practices for building performant,
            accessible, and maintainable applications with HeroUI components.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>
    </Accordion>
  )
}

Controlled

Expanded: getting-started

Learn the basics of HeroUI and how to integrate it into your React project. This section covers installation, setup, and your first component.

import { ChevronDown, ChevronUp } from "gravity-icons-solid"
import {
  Accordion,
  Button,
  type Key,
  useDisclosureGroupNavigation
} from "heroui-solid"
import { createSignal, For } from "solid-js"

const items = [
  {
    content:
      "Learn the basics of HeroUI and how to integrate it into your React project. This section covers installation, setup, and your first component.",
    id: "getting-started",
    title: "Getting Started"
  },
  {
    content:
      "Understand the fundamental concepts behind HeroUI, including the compound component pattern, styling with Tailwind CSS, and accessibility features.",
    id: "core-concepts",
    title: "Core Concepts"
  },
  {
    content:
      "Explore advanced features like custom variants, theme customization, and integration with other libraries in your React ecosystem.",
    id: "advanced-usage",
    title: "Advanced Usage"
  }
]

export function Controlled() {
  const [expandedKeys, setExpandedKeys] = createSignal<Set<Key>>(
    new Set(["getting-started"])
  )
  const itemIds = items.map((item) => item.id)

  const { isNextDisabled, isPrevDisabled, onNext, onPrevious } =
    useDisclosureGroupNavigation({
      expandedKeys,
      itemIds,
      onExpandedChange: setExpandedKeys
    })

  return (
    <div class="w-full max-w-md">
      <div class="mb-4 flex items-center justify-between">
        <p class="text-sm text-muted">
          Expanded: <strong>{[...expandedKeys()].join(", ") || "none"}</strong>
        </p>
        <div class="flex gap-2">
          <Button
            aria-label="Previous item"
            isDisabled={isPrevDisabled()}
            size="sm"
            variant="secondary"
            onClick={onPrevious}
          >
            <ChevronUp class="size-4" />
          </Button>
          <Button
            aria-label="Next item"
            isDisabled={isNextDisabled()}
            size="sm"
            variant="secondary"
            onClick={onNext}
          >
            <ChevronDown class="size-4" />
          </Button>
        </div>
      </div>
      <Accordion
        expandedKeys={expandedKeys()}
        onExpandedChange={setExpandedKeys}
      >
        <For each={items}>
          {(item) => (
            <Accordion.Item id={item.id}>
              <Accordion.Heading>
                <Accordion.Trigger>
                  {item.title}
                  <Accordion.Indicator />
                </Accordion.Trigger>
              </Accordion.Heading>
              <Accordion.Panel>
                <Accordion.Body>{item.content}</Accordion.Body>
              </Accordion.Panel>
            </Accordion.Item>
          )}
        </For>
      </Accordion>
    </div>
  )
}

Custom Indicator

import {
  ChevronsDown,
  CircleChevronDown,
  Minus,
  Plus
} from "gravity-icons-solid"
import { Accordion, type Key } from "heroui-solid"
import { createSignal, Show } from "solid-js"

export function CustomIndicator() {
  const [expandedKeys, setExpandedKeys] = createSignal<Set<Key>>(new Set([""]))

  return (
    <Accordion
      class="w-full max-w-md"
      expandedKeys={expandedKeys()}
      variant="surface"
      onExpandedChange={setExpandedKeys}
    >
      <Accordion.Item id="1">
        <Accordion.Heading>
          <Accordion.Trigger>
            Using Plus/Minus Icon
            <Accordion.Indicator>
              <Show when={expandedKeys().has("1")} fallback={<Plus />}>
                <Minus />
              </Show>
            </Accordion.Indicator>
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            This accordion uses a plus icon that transforms when expanded. The
            icon automatically rotates 45 degrees to form an X.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>

      <Accordion.Item id="2">
        <Accordion.Heading>
          <Accordion.Trigger>
            Using Caret Icon
            <Accordion.Indicator>
              <CircleChevronDown />
            </Accordion.Indicator>
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            This item uses a caret icon for the indicator. The rotation
            animation is applied automatically.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>

      <Accordion.Item id="3">
        <Accordion.Heading>
          <Accordion.Trigger>
            Using Arrow Icon
            <Accordion.Indicator>
              <ChevronsDown />
            </Accordion.Indicator>
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            This item uses an arrow icon. Any icon you pass will receive the
            rotation animation when the item expands.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>
    </Accordion>
  )
}

Disabled State

Entire accordion disabled

Individual items disabled

import { Accordion } from "heroui-solid"

export function Disabled() {
  return (
    <div class="flex w-full flex-col items-center gap-8">
      <div class="w-full max-w-md space-y-2">
        <h3 class="text-sm font-medium text-muted">
          Entire accordion disabled
        </h3>
        <Accordion isDisabled class="w-full max-w-md">
          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                Disabled Item 1
                <Accordion.Indicator />
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>
                This content cannot be accessed when the accordion is disabled.
              </Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                Disabled Item 2
                <Accordion.Indicator />
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>
                This content cannot be accessed when the accordion is disabled.
              </Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>
        </Accordion>
      </div>

      <div class="w-full max-w-md space-y-2">
        <h3 class="text-sm font-medium text-muted">
          Individual items disabled
        </h3>
        <Accordion class="w-full max-w-md">
          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                Active Item
                <Accordion.Indicator />
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>
                This item is active and can be toggled normally.
              </Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item isDisabled>
            <Accordion.Heading>
              <Accordion.Trigger>
                Disabled Item
                <Accordion.Indicator />
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>
                This content cannot be accessed when the item is disabled.
              </Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>

          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                Another Active Item
                <Accordion.Indicator />
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>
                This item is also active and can be toggled.
              </Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>
        </Accordion>
      </div>
    </div>
  )
}

FAQ Layout

Frequently Asked Questions

Everything you need to know about licensing and usage.

General

Licensing

Support

import { ChevronDown } from "gravity-icons-solid"
import { Accordion } from "heroui-solid"
import { For } from "solid-js"

export function FAQ() {
  const categories = [
    {
      items: [
        {
          content:
            "Browse our products, add items to your cart, and proceed to checkout. You'll need to provide shipping and payment information to complete your purchase.",
          title: "How do I place an order?"
        },
        {
          content:
            "Yes, you can modify or cancel your order before it's shipped. Once your order is processed, you can't make changes.",
          title: "Can I modify or cancel my order?"
        }
      ],
      title: "General"
    },
    {
      items: [
        {
          content:
            "You can purchase a license directly from our website. Select the license type that fits your needs and proceed to checkout.",
          title: "How do I purchase a license?"
        },
        {
          content:
            "A standard license is for personal use or small projects, while a pro license includes commercial use rights and priority support.",
          title: "What is the difference between a standard and a pro license?"
        }
      ],
      title: "Licensing"
    },
    {
      items: [
        {
          content:
            "You can reach our support team through the contact form on our website, or email us directly at support@example.com.",
          title: "How do I get support?"
        }
      ],
      title: "Support"
    }
  ]

  return (
    <div class="flex w-full flex-col gap-6">
      <div class="flex flex-col gap-1">
        <h2 class="text-2xl font-bold">Frequently Asked Questions</h2>
        <p class="mb-4 text-lg font-medium text-muted">
          Everything you need to know about licensing and usage.
        </p>
      </div>
      <For each={categories}>
        {(category) => (
          <div>
            <p class="text-md mb-2 font-medium text-muted">{category.title}</p>
            <Accordion class="w-full" variant="surface">
              <For each={category.items}>
                {(item) => (
                  <Accordion.Item>
                    <Accordion.Heading>
                      <Accordion.Trigger>
                        {item.title}
                        <Accordion.Indicator>
                          <ChevronDown />
                        </Accordion.Indicator>
                      </Accordion.Trigger>
                    </Accordion.Heading>
                    <Accordion.Panel>
                      <Accordion.Body>{item.content}</Accordion.Body>
                    </Accordion.Panel>
                  </Accordion.Item>
                )}
              </For>
            </Accordion>
          </div>
        )}
      </For>
    </div>
  )
}

Custom Styles

import { ChevronDown } from "gravity-icons-solid"
import { Accordion, cn } from "heroui-solid"
import { For } from "solid-js"

const items = [
  {
    content:
      "Stay informed about your account activity with real-time notifications. ",
    iconUrl:
      "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/3dicons/bell-small.png",
    subtitle: "Receive account activity updates",
    title: "Set Up Notifications"
  },
  {
    content:
      "Enhance your browsing experience by installing our official browser extension",
    iconUrl:
      "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/3dicons/compass-small.png",
    subtitle: "Connect you browser to your account",
    title: "Set up Browser Extension"
  },
  {
    content:
      "Begin your journey into the world of digital collectibles by creating your first NFT. ",
    iconUrl:
      "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/3dicons/mint-collective-small.png",
    subtitle: "Create your first collectible",
    title: "Mint Collectible"
  }
]

export function CustomStyles() {
  return (
    <Accordion
      class="bg-surface-1/10 w-full max-w-md rounded-2xl"
      variant="surface"
    >
      <For each={items}>
        {(item) => (
          <Accordion.Item
            class={cn(
              "group/item",
              "first:[&_[data-slot=accordion-trigger]]:rounded-t-2xl", // First trigger we want to round the top
              "last:[&:not(:has([data-slot=accordion-trigger][aria-expanded='true']))_[data-slot=accordion-trigger]]:rounded-b-2xl" // Last trigger we want to round the bottom
            )}
          >
            <Accordion.Heading>
              <Accordion.Trigger class="hover:bgsurface group flex items-center gap-2 transition-none">
                {item.iconUrl ? (
                  <img
                    alt={item.title}
                    class="h-11 w-11 transition-[scale,rotate] duration-300 ease-out group-hover/item:scale-120 group-hover/item:-rotate-10 group-hover/item:drop-shadow-lg"
                    src={item.iconUrl}
                  />
                ) : null}
                <div class="flex flex-col gap-0">
                  <span class="leading-5 font-medium">{item.title}</span>
                  <span class="leading-6 font-normal text-muted/80">
                    {item.subtitle}
                  </span>
                </div>
                <Accordion.Indicator class="text-muted/50 [&>svg]:size-4">
                  <ChevronDown />
                </Accordion.Indicator>
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body class="text-muted/80">
                {item.content}
              </Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>
        )}
      </For>
    </Accordion>
  )
}

Without Separator

import {
  ChevronDown,
  CreditCard,
  Receipt,
  ShoppingBag
} from "gravity-icons-solid"
import { Accordion } from "heroui-solid"
import { For, type JSX } from "solid-js"

const items: Array<{ content: string; icon: JSX.Element; title: string }> = [
  {
    content:
      "Browse our products, add items to your cart, and proceed to checkout. You'll need to provide shipping and payment information to complete your purchase.",
    icon: <ShoppingBag />,
    title: "How do I place an order?"
  },
  {
    content:
      "Yes, you can modify or cancel your order before it's shipped. Once your order is processed, you can't make changes.",
    icon: <Receipt />,
    title: "Can I modify or cancel my order?"
  },
  {
    content:
      "We accept all major credit cards, including Visa, Mastercard, and American Express.",
    icon: <CreditCard />,
    title: "What payment methods do you accept?"
  }
]

export function WithoutSeparator() {
  return (
    <Accordion hideSeparator class="w-full max-w-md">
      <For each={items}>
        {(item) => (
          <Accordion.Item>
            <Accordion.Heading>
              <Accordion.Trigger>
                {item.icon ? (
                  <span class="mr-3 size-4 shrink-0 text-muted">
                    {item.icon}
                  </span>
                ) : null}
                {item.title}
                <Accordion.Indicator>
                  <ChevronDown />
                </Accordion.Indicator>
              </Accordion.Trigger>
            </Accordion.Heading>
            <Accordion.Panel>
              <Accordion.Body>{item.content}</Accordion.Body>
            </Accordion.Panel>
          </Accordion.Item>
        )}
      </For>
    </Accordion>
  )
}

Custom Element

HeroUI React overrides the rendered elements with a render prop. This port uses Kobalte's polymorphic as prop instead — for example, a section root with article items:

import { Accordion } from "heroui-solid"

export function CustomElement() {
  return (
    <Accordion as="section" class="w-full max-w-md">
      <Accordion.Item as="article">
        <Accordion.Heading as="h4">
          <Accordion.Trigger>
            Custom Elements
            <Accordion.Indicator />
          </Accordion.Trigger>
        </Accordion.Heading>
        <Accordion.Panel>
          <Accordion.Body>
            This accordion renders a section root, an article item, and an h4
            heading via Kobalte's polymorphic as prop.
          </Accordion.Body>
        </Accordion.Panel>
      </Accordion.Item>
    </Accordion>
  )
}
  • DisclosureGroup: Group of collapsible panels (not ported yet)
  • Disclosure: Single collapsible content section (not ported yet)

Styling

Passing Tailwind CSS classes

import { Accordion, cn } from "heroui-solid";

function CustomAccordion() {
  return (
    <Accordion class="bg-surface-1/10 w-full max-w-md rounded-2xl" variant="surface">
      <Accordion.Item class={cn("group/item", "first:[&_[data-slot=accordion-trigger]]:rounded-t-2xl")}>
        ...
      </Accordion.Item>
    </Accordion>
  );
}

Customizing the component classes

To customize the Accordion component classes, you can use the @layer components directive. Learn more.

@layer components {
  .accordion {
    @apply rounded-xl bg-gray-50;
  }

  .accordion__trigger {
    @apply font-semibold text-lg;
  }

  .accordion--outline {
    @apply shadow-lg border-2;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Accordion component uses these CSS classes (View source styles):

Base Classes

  • .accordion - Base accordion container
  • .accordion__body - Content body container
  • .accordion__heading - Heading wrapper
  • .accordion__indicator - Expand/collapse indicator icon
  • .accordion__item - Individual accordion item
  • .accordion__panel - Collapsible panel container
  • .accordion__trigger - Clickable trigger button

Variant Classes

  • .accordion--surface - Surface variant with background and rounded corners

State Classes

  • .accordion__trigger[aria-expanded="true"] - Expanded state
  • .accordion__panel[data-expanded="true"] - Panel visible state

Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover on trigger
  • Focus: :focus-visible on trigger
  • Disabled: :disabled or [aria-disabled="true"] on trigger
  • Expanded: [aria-expanded="true"] on trigger

API Reference

Accordion Props

PropTypeDefaultDescription
allowsMultipleExpandedbooleanfalseWhether multiple items can be expanded at once
defaultExpandedKeysIterable<Key>-The initial expanded keys
expandedKeysIterable<Key>-The controlled expanded keys
onExpandedChange(keys: Set<Key>) => void-Handler called when expanded keys change
isDisabledbooleanfalseWhether the entire accordion is disabled
variant"default" | "surface""default"The visual variant of the accordion
hideSeparatorbooleanfalseHide separator lines between accordion items
classstring-Additional CSS classes
childrenJSX.Element-The accordion items
asValidComponent"div"Overrides the default DOM element (Kobalte polymorphic as)

Accordion.Item Props

PropTypeDefaultDescription
idKey-Unique identifier for the item
isDisabledbooleanfalseWhether this item is disabled
classstring-Additional CSS classes
childrenJSX.Element-The item content
asValidComponent"div"Overrides the default DOM element (Kobalte polymorphic as)

Accordion.Trigger Props

PropTypeDefaultDescription
classstring-Additional CSS classes
childrenJSX.Element-Trigger content
onClickJSX.EventHandlerUnion<HTMLElement, MouseEvent>-Additional click handler
asValidComponent"button"Overrides the default DOM element (Kobalte polymorphic as)

Accordion.Panel Props

PropTypeDefaultDescription
classstring-Additional CSS classes
childrenJSX.Element-Panel content
asValidComponent"div"Overrides the default DOM element (Kobalte polymorphic as)

Accordion.Indicator Props

PropTypeDefaultDescription
classstring-Additional CSS classes
childrenJSX.Element-Custom indicator icon

Accordion.Body Props

PropTypeDefaultDescription
classstring-Additional CSS classes
childrenJSX.Element-Body content

Differences from HeroUI React

  • Use onClick (Solid's native event) instead of React Aria's onPress.
  • Polymorphism uses Kobalte's as prop instead of React's render prop override.
  • onExpandedChange reports keys as strings (numeric item ids are coerced).
  • A custom Accordion.Indicator icon renders inside a span wrapper carrying the indicator class (Solid has no cloneElement), so selectors like [&>svg]:size-4 target the icon as expected.

Last updated: 7/19/26, 3:27 AM

HeroUI SolidUnofficial SolidJS port of HeroUI v3, built on Kobalte and @heroui/styles