Skip to content
Navigation

Collapsible

Added 14 October 2026

React

Codecomponents/react/collapsible-demo.tsx
import {
    Collapsible,
    CollapsibleContent,
    CollapsibleTrigger,
    CollapsibleCard,
    CollapsibleCardContent,
    CollapsibleCardHeader,
} from '@stroeer-labs/design-library/react';
import {CardDescription, CardIcon, CardTitle} from '@stroeer-labs/design-library/react';
import {Calendar, ChevronDown} from 'lucide-react';

const triggerClass = 'flex w-full items-center justify-between rounded-md border border-border bg-card px-4 py-2 text-sm font-medium hover:bg-accent';
const chevronClass = 'size-4 text-muted-foreground transition-transform duration-200 motion-reduce:transition-none [[data-panel-open]_&]:rotate-180';

export function CollapsibleDemo() {
    return (
        <div className="space-y-10">
            <section className="space-y-4">
                <h3 className="text-sm font-semibold">Collapsible</h3>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Default (closed)</p>
                    <Collapsible className="w-full max-w-sm space-y-2">
                        <CollapsibleTrigger className={triggerClass}>
                            Campaign details
                            <ChevronDown aria-hidden="true" className={chevronClass} />
                        </CollapsibleTrigger>
                        <CollapsibleContent>
                            <div className="rounded-md border border-border bg-card px-4 py-3">
                                <p className="text-sm text-muted-foreground">This content is hidden until the trigger is clicked.</p>
                            </div>
                        </CollapsibleContent>
                    </Collapsible>
                </div>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Default open</p>
                    <Collapsible defaultOpen className="w-full max-w-sm space-y-2">
                        <CollapsibleTrigger className={triggerClass}>
                            Campaign details
                            <ChevronDown aria-hidden="true" className={chevronClass} />
                        </CollapsibleTrigger>
                        <CollapsibleContent>
                            <div className="rounded-md border border-border bg-card px-4 py-3">
                                <p className="text-sm text-muted-foreground">This content is visible by default.</p>
                            </div>
                        </CollapsibleContent>
                    </Collapsible>
                </div>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Disabled</p>
                    <Collapsible disabled className="w-full max-w-sm space-y-2">
                        <CollapsibleTrigger className={triggerClass}>
                            Campaign details
                            <ChevronDown aria-hidden="true" className={chevronClass} />
                        </CollapsibleTrigger>
                        <CollapsibleContent>
                            <div className="rounded-md border border-border bg-card px-4 py-3">
                                <p className="text-sm text-muted-foreground">This content stays hidden.</p>
                            </div>
                        </CollapsibleContent>
                    </Collapsible>
                </div>
            </section>

            <section className="space-y-4">
                <h3 className="text-sm font-semibold">Collapsible Card</h3>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Default (closed)</p>
                    <CollapsibleCard className="w-full">
                        <CollapsibleCardHeader>
                            <CardTitle>Campaign details</CardTitle>
                            <CardDescription>Click to expand</CardDescription>
                        </CollapsibleCardHeader>
                        <CollapsibleCardContent>
                            <p className="text-sm text-muted-foreground">This content is hidden until the header is clicked.</p>
                        </CollapsibleCardContent>
                    </CollapsibleCard>
                </div>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Default open</p>
                    <CollapsibleCard defaultOpen className="w-full">
                        <CollapsibleCardHeader>
                            <CardTitle>Campaign details</CardTitle>
                            <CardDescription>Click to collapse</CardDescription>
                        </CollapsibleCardHeader>
                        <CollapsibleCardContent>
                            <p className="text-sm text-muted-foreground">This content is visible by default.</p>
                        </CollapsibleCardContent>
                    </CollapsibleCard>
                </div>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Disabled</p>
                    <CollapsibleCard disabled className="w-full">
                        <CollapsibleCardHeader>
                            <CardTitle>Campaign details</CardTitle>
                            <CardDescription>Clicking does nothing</CardDescription>
                        </CollapsibleCardHeader>
                        <CollapsibleCardContent>
                            <p className="text-sm text-muted-foreground">This content stays hidden.</p>
                        </CollapsibleCardContent>
                    </CollapsibleCard>
                </div>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Leading icon — CardIcon slot</p>
                    <CollapsibleCard className="w-full">
                        <CollapsibleCardHeader>
                            <CardIcon>
                                <Calendar />
                            </CardIcon>
                            <CardTitle>Schedule</CardTitle>
                            <CardDescription>When should your campaign run?</CardDescription>
                        </CollapsibleCardHeader>
                        <CollapsibleCardContent>
                            <p className="text-sm text-muted-foreground">Scheduling details live here.</p>
                        </CollapsibleCardContent>
                    </CollapsibleCard>
                </div>
                <div className="space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Size sm</p>
                    <CollapsibleCard size="sm" defaultOpen className="w-full">
                        <CollapsibleCardHeader>
                            <CardTitle>Compact card</CardTitle>
                        </CollapsibleCardHeader>
                        <CollapsibleCardContent>
                            <p className="text-sm text-muted-foreground">Compact collapsible content.</p>
                        </CollapsibleCardContent>
                    </CollapsibleCard>
                </div>
            </section>
        </div>
    );
}

Angular

Codecomponents/angular/collapsible-demo.ts
import '@angular/compiler';
import {Component} from '@angular/core';
import {NgIcon, provideIcons} from '@ng-icons/core';
import {lucideCalendar, lucideChevronDown} from '@ng-icons/lucide';
import {HlmCollapsibleImports} from '@stroeer-labs/design-library/angular';
import {HlmCollapsibleCardImports} from '@stroeer-labs/design-library/angular';
import {HlmCardImports} from '@stroeer-labs/design-library/angular';

@Component({
    selector: 'dl-collapsible-demo',
    standalone: true,
    imports: [HlmCollapsibleImports, HlmCollapsibleCardImports, HlmCardImports, NgIcon],
    viewProviders: [provideIcons({lucideCalendar, lucideChevronDown})],
    template: `
    <div class="space-y-10">
      <section class="space-y-4">
        <h3 class="text-sm font-semibold">Collapsible</h3>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Default (closed)</p>
          <hlm-collapsible class="w-full max-w-sm space-y-2">
            <button
              hlmCollapsibleTrigger
              class="flex w-full items-center justify-between rounded-md border border-border bg-card px-4 py-2 text-sm font-medium hover:bg-accent"
            >
              Campaign details
              <ng-icon
                name="lucideChevronDown"
                aria-hidden="true"
                class="text-[length:--spacing(4)] text-muted-foreground transition-transform duration-200 motion-reduce:transition-none [[data-slot=collapsible-trigger][data-state=open]_&]:rotate-180"
              />
            </button>
            <hlm-collapsible-content>
              <div class="rounded-md border border-border bg-card px-4 py-3">
                <p class="text-sm text-muted-foreground">
                  This content is hidden until the trigger is clicked.
                </p>
              </div>
            </hlm-collapsible-content>
          </hlm-collapsible>
        </div>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Default open</p>
          <hlm-collapsible [expanded]="true" class="w-full max-w-sm space-y-2">
            <button
              hlmCollapsibleTrigger
              class="flex w-full items-center justify-between rounded-md border border-border bg-card px-4 py-2 text-sm font-medium hover:bg-accent"
            >
              Campaign details
              <ng-icon
                name="lucideChevronDown"
                aria-hidden="true"
                class="text-[length:--spacing(4)] text-muted-foreground transition-transform duration-200 motion-reduce:transition-none [[data-slot=collapsible-trigger][data-state=open]_&]:rotate-180"
              />
            </button>
            <hlm-collapsible-content>
              <div class="rounded-md border border-border bg-card px-4 py-3">
                <p class="text-sm text-muted-foreground">This content is visible by default.</p>
              </div>
            </hlm-collapsible-content>
          </hlm-collapsible>
        </div>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Disabled</p>
          <hlm-collapsible disabled class="w-full max-w-sm space-y-2">
            <button
              hlmCollapsibleTrigger
              class="flex w-full items-center justify-between rounded-md border border-border bg-card px-4 py-2 text-sm font-medium hover:bg-accent"
            >
              Campaign details
              <ng-icon
                name="lucideChevronDown"
                aria-hidden="true"
                class="text-[length:--spacing(4)] text-muted-foreground transition-transform duration-200 motion-reduce:transition-none [[data-slot=collapsible-trigger][data-state=open]_&]:rotate-180"
              />
            </button>
            <hlm-collapsible-content>
              <div class="rounded-md border border-border bg-card px-4 py-3">
                <p class="text-sm text-muted-foreground">This content stays hidden.</p>
              </div>
            </hlm-collapsible-content>
          </hlm-collapsible>
        </div>
      </section>

      <section class="space-y-4">
        <h3 class="text-sm font-semibold">Collapsible Card</h3>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Default (closed)</p>
          <hlm-collapsible-card class="w-full">
            <hlm-collapsible-card-header>
              <div hlmCardTitle>Campaign details</div>
              <div hlmCardDescription>Click to expand</div>
            </hlm-collapsible-card-header>
            <hlm-collapsible-card-content>
              <p class="text-sm text-muted-foreground">
                This content is hidden until the header is clicked.
              </p>
            </hlm-collapsible-card-content>
          </hlm-collapsible-card>
        </div>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Default open</p>
          <hlm-collapsible-card [expanded]="true" class="w-full">
            <hlm-collapsible-card-header>
              <div hlmCardTitle>Campaign details</div>
              <div hlmCardDescription>Click to collapse</div>
            </hlm-collapsible-card-header>
            <hlm-collapsible-card-content>
              <p class="text-sm text-muted-foreground">This content is visible by default.</p>
            </hlm-collapsible-card-content>
          </hlm-collapsible-card>
        </div>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Disabled</p>
          <hlm-collapsible-card disabled class="w-full">
            <hlm-collapsible-card-header>
              <div hlmCardTitle>Campaign details</div>
              <div hlmCardDescription>Clicking does nothing</div>
            </hlm-collapsible-card-header>
            <hlm-collapsible-card-content>
              <p class="text-sm text-muted-foreground">This content stays hidden.</p>
            </hlm-collapsible-card-content>
          </hlm-collapsible-card>
        </div>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Leading icon — hlmCardIcon slot</p>
          <hlm-collapsible-card class="w-full">
            <hlm-collapsible-card-header>
              <div hlmCardIcon><ng-icon name="lucideCalendar" /></div>
              <div hlmCardTitle>Schedule</div>
              <div hlmCardDescription>When should your campaign run?</div>
            </hlm-collapsible-card-header>
            <hlm-collapsible-card-content>
              <p class="text-sm text-muted-foreground">Scheduling details live here.</p>
            </hlm-collapsible-card-content>
          </hlm-collapsible-card>
        </div>
        <div class="space-y-2">
          <p class="text-xs font-medium text-muted-foreground">Size sm</p>
          <hlm-collapsible-card size="sm" [expanded]="true" class="w-full">
            <hlm-collapsible-card-header>
              <div hlmCardTitle>Compact card</div>
            </hlm-collapsible-card-header>
            <hlm-collapsible-card-content>
              <p class="text-sm text-muted-foreground">Compact collapsible content.</p>
            </hlm-collapsible-card-content>
          </hlm-collapsible-card>
        </div>
      </section>
    </div>
  `,
})
export class CollapsibleDemoComponent {}