MenuChevron Down
Collapsible - Docs - Artefact

Collapsible

Overlays
Auto-interactive

Introduction

An interactive component that can be expanded or collapsed to show or hide content.

Usage

Basic Collapsible

Additional details go here.

import { Collapsible } from "../components/ui";

export default function MyPage() {
  return (
    <Collapsible
      trigger="Show more"
      content={<p>Additional details go here.</p>}
      defaultOpen
    />
  );
}

With Indicator and Controlled State

import { Collapsible } from "../components/ui";

export default function MyPage() {
  return (
    <Collapsible
      trigger="Details"
      content={<p>Content revealed on toggle.</p>}
      indicatorPlacement="start"
      onOpenChange={(open) => console.log("open:", open)}
    />
  );
}

CMS Page Builder

This component is available as a collapsible block in the Page Builder (content/pages/*.json). trigger is a nested block list (the CMS always submits an array, even for a single trigger element):

{
  "type": "collapsible",
  "trigger": [{ "type": "button", "text": "Show more" }],
  "showIndicator": true,
  "children": [
    { "type": "text", "content": "Additional details go here." }
  ]
}

Props

PropTypeDescription

| trigger | `JSX.Element \ | string` | The trigger element or string. A string is wrapped in a button. |

| content | JSX.Element | The content to be shown or hidden. | | indicator | JSX.Element | Optional indicator element (e.g. a chevron). |

| indicatorPlacement | `"start" \ | "end"` | Where to place the indicator relative to the trigger. Default: "end". |

| open | boolean | Whether the collapsible is open (controlled). | | defaultOpen | boolean | Whether the collapsible is open by default (uncontrolled). | | onOpenChange | (open: boolean) => void | Callback for when the open state changes. | | disabled | boolean | Whether the collapsible is disabled. | | interactive | boolean | Enable client-side interactivity. Collapsible is Tier-1 (auto-interactive): it always hydrates as an island unless you pass interactive={false}. | | class | string | Root element class name. | | triggerClass | string | Trigger element class name. | | contentClass | string | Content element class name. | | indicatorClass | string | Indicator element class name. | | id | string | ID for the collapsible. |

Hydration

Collapsible is classified as Tier-1 (auto-interactive).

  • It always renders as a hydrated client island (it needs JS to expand/collapse and to run onOpenChange).
  • The only way to opt out of hydration is to pass interactive={false}, in which case it renders the static *-primitive markup without the toggle behavior.
  • This is implemented via the shared shouldHydrate(interactive, true) predicate in app/components/ui/island-utils.ts, the single source of truth for all hydration decisions.