shadimage
rescript-shadcn
uiAccordionsource: ok · refreshed

Accordion

npx shadcn add "https://rescript-shadcn.miriad.studio/r/Accordion.json"
free

Interaction

accordion

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light
ui-primitives@base-ui/react
iconslucide-react

Registry dependencies

@rescript-shadcn/Icons

Files1 · source cached 10/8/2026, 4:44:54 AM

registry/base/ui/Accordion.res
@@directive("'use client'")

@module("cn")
external cn: (string, option<string>) => string = "cn"

@react.componentWithProps(BaseUi.Accordion.Root.props)
let make = (props: BaseUi.Accordion.Root.props<'value>) =>
  <BaseUi.Accordion.Root
    {...props}
    dataSlot={props.dataSlot->Option.getOr("accordion")}
    className={cn(" flex w-full flex-col", props.className)}
  />

module Multiple = {
  @react.componentWithProps(BaseUi.Accordion.Root.props)
  let make = (props: BaseUi.Accordion.Root.props<'value>) =>
    <BaseUi.Accordion.Root
      {...props}
      multiple=true
      dataSlot={props.dataSlot->Option.getOr("accordion")}
      className={cn(" flex w-full flex-col", props.className)}
    />
}

module Item = {
  @react.componentWithProps(BaseUi.Accordion.Item.props)
  let make = (props: BaseUi.Accordion.Item.props<'value>) =>
    <BaseUi.Accordion.Item
      {...props}
      dataSlot={props.dataSlot->Option.getOr("accordion-item")}
      className={cn("not-last:border-b", props.className)}
    />
}

module Trigger = {
  @react.componentWithProps(BaseUi.Accordion.Trigger.props)
  let make = (props: BaseUi.Accordion.Trigger.props) =>
    <BaseUi.Accordion.Header className="flex">
      <BaseUi.Accordion.Trigger
        {...props}
        dataSlot={props.dataSlot->Option.getOr("accordion-trigger")}
        className={cn(
          "focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:after:border-ring **:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-lg py-2.5 text-left text-sm font-medium hover:underline focus-visible:ring-3 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between border border-transparent transition-all outline-none aria-disabled:pointer-events-none aria-disabled:opacity-50",
          props.className,
        )}
      >
        {props.children->Option.getOr(React.null)}
        <Icons.ChevronDown
          dataSlot="accordion-trigger-icon"
          className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
        />
        <Icons.ChevronUp
          dataSlot="accordion-trigger-icon"
          className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
        />
      </BaseUi.Accordion.Trigger>
    </BaseUi.Accordion.Header>
}

module Content = {
  type props = BaseUi.Types.BaseUIComponentProps.t

  let toBaseUiProps: props => BaseUi.Types.BaseUIComponentProps.t = %raw(`({className, ...props}) => props`)

  @react.componentWithProps(props)
  let make = (props: props) => {
    let children = props.children
    <BaseUi.Accordion.Panel
      {...props->toBaseUiProps}
      dataSlot={props.dataSlot->Option.getOr("accordion-content")}
      className="data-open:animate-accordion-down data-closed:animate-accordion-up text-sm overflow-hidden"
    >
      <div
        className={cn(
          "pt-0 pb-2.5 [&_a]:hover:text-foreground h-(--accordion-panel-height) data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_p:not(:last-child)]:mb-4",
          props.className,
        )}
        ?children
      />
    </BaseUi.Accordion.Panel>
  }
}

More from rescript-shadcn

Browse all components in this library →