Collapsible
An interactive component which expands/collapses a panel.
Code
import { Button, ChevronsUpDownIcon, Collapsible, CollapsibleContent, CollapsibleTrigger,} from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [isOpen, setIsOpen] = useState(false);
return ( <Collapsible open={isOpen} onOpenChange={setIsOpen} className="tw:flex tw:w-[350px] tw:flex-col tw:gap-2" > <div className="tw:flex tw:items-center tw:justify-between tw:gap-4 tw:px-4"> <h4 className="tw:text-sm tw:font-semibold">Order #4189</h4> <CollapsibleTrigger render={<Button variant="ghost" size="icon" className="tw:size-8" />} > <ChevronsUpDownIcon /> <span className="tw:sr-only">Toggle details</span> </CollapsibleTrigger> </div> <div className="tw:flex tw:items-center tw:justify-between tw:rounded-md tw:border tw:border-border tw:px-4 tw:py-2 tw:text-sm"> <span className="tw:text-muted-foreground">Status</span> <span className="tw:font-medium">Shipped</span> </div> <CollapsibleContent className="tw:flex tw:flex-col tw:gap-2"> <div className="tw:rounded-md tw:border tw:border-border tw:px-4 tw:py-2 tw:text-sm"> <p className="tw:font-medium">Shipping address</p> <p className="tw:text-muted-foreground"> 4820 County Road 12, Ames, IA </p> </div> <div className="tw:rounded-md tw:border tw:border-border tw:px-4 tw:py-2 tw:text-sm"> <p className="tw:font-medium">Items</p> <p className="tw:text-muted-foreground">2x Liquid Fertilizer Totes</p> </div> </CollapsibleContent> </Collapsible> );}Composition
Section titled “Composition”Use the following composition to build a Collapsible:
Collapsible├── CollapsibleTrigger└── CollapsibleContentControlled State
Section titled “Controlled State”Use the open and onOpenChange props to control the state.
Code
import { Collapsible, CollapsibleContent, CollapsibleTrigger,} from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [open, setOpen] = useState(false);
return ( <Collapsible open={open} onOpenChange={setOpen}> <CollapsibleTrigger>Toggle</CollapsibleTrigger> <CollapsibleContent>Content</CollapsibleContent> </Collapsible> );}Code
import { Button, Card, CardContent, ChevronDownIcon, Collapsible, CollapsibleContent, CollapsibleTrigger,} from "@falcon/ui-kit";
export function Example() { return ( <Card className="tw:mx-auto tw:w-full tw:max-w-sm"> <CardContent> <Collapsible className="tw:rounded-md tw:data-open:bg-muted"> <CollapsibleTrigger render={<Button variant="ghost" className="tw:w-full" />} > Product details <ChevronDownIcon className="tw:ml-auto tw:group-data-panel-open/button:rotate-180" /> </CollapsibleTrigger> <CollapsibleContent className="tw:flex tw:flex-col tw:items-start tw:gap-2 tw:p-2.5 tw:pt-0 tw:text-sm"> <div> This panel can be expanded or collapsed to reveal additional content. </div> <Button size="xs">Learn More</Button> </CollapsibleContent> </Collapsible> </CardContent> </Card> );}Settings Panel
Section titled “Settings Panel”Use a trigger button to reveal additional settings.
Code
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Collapsible, CollapsibleContent, CollapsibleTrigger, Field, FieldGroup, FieldLabel, Input, MaximizeIcon, MinimizeIcon,} from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [isOpen, setIsOpen] = useState(false);
return ( <Card className="tw:mx-auto tw:w-full tw:max-w-xs" size="sm"> <CardHeader> <CardTitle>Radius</CardTitle> <CardDescription>Set the corner radius of the element.</CardDescription> </CardHeader> <CardContent> <Collapsible open={isOpen} onOpenChange={setIsOpen} className="tw:flex tw:items-start tw:gap-2" > <FieldGroup className="tw:grid tw:w-full tw:grid-cols-2 tw:gap-2"> <Field> <FieldLabel htmlFor="radius-x" className="tw:sr-only"> Radius X </FieldLabel> <Input id="radius-x" placeholder="0" defaultValue={0} /> </Field> <Field> <FieldLabel htmlFor="radius-y" className="tw:sr-only"> Radius Y </FieldLabel> <Input id="radius-y" placeholder="0" defaultValue={0} /> </Field> <CollapsibleContent className="tw:col-span-full tw:grid tw:grid-cols-subgrid tw:gap-2"> <Field> <FieldLabel htmlFor="radius-x-2" className="tw:sr-only"> Radius X </FieldLabel> <Input id="radius-x-2" placeholder="0" defaultValue={0} /> </Field> <Field> <FieldLabel htmlFor="radius-y-2" className="tw:sr-only"> Radius Y </FieldLabel> <Input id="radius-y-2" placeholder="0" defaultValue={0} /> </Field> </CollapsibleContent> </FieldGroup> <CollapsibleTrigger aria-label="Toggle additional settings" render={<Button variant="outline" size="icon" />} > {isOpen ? <MinimizeIcon /> : <MaximizeIcon />} </CollapsibleTrigger> </Collapsible> </CardContent> </Card> );}File Tree
Section titled “File Tree”Use nested collapsibles to build a file tree.
Code
import { Button, Card, CardContent, CardHeader, ChevronRightIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, FileIcon, FolderIcon, Tabs, TabsList, TabsTrigger,} from "@falcon/ui-kit";
type FileTreeItem = { name: string } | { name: string; items: FileTreeItem[] };
export function Example() { const fileTree: FileTreeItem[] = [ { name: "agronomy", items: [ { name: "field-plans", items: [ { name: "north-40.pdf" }, { name: "south-quarter.pdf" }, { name: "creek-bottom.pdf" }, { name: "home-place.pdf" }, { name: "section-12.pdf" }, { name: "west-80.pdf" }, ], }, { name: "soil-samples.xlsx" }, { name: "tissue-results.xlsx" }, ], }, { name: "agreements", items: [ { name: "credit-application.pdf" }, { name: "prepay-2026.pdf" }, { name: "storage-contract.pdf" }, ], }, { name: "invoices", items: [ { name: "inv-2026-0141.pdf" }, { name: "inv-2026-0159.pdf" }, { name: "inv-2026-0163.pdf" }, ], }, { name: "labels", items: [{ name: "glyphosate-sds.pdf" }, { name: "atrazine-sds.pdf" }], }, { name: "scouting", items: [ { name: "weed-pressure.jpg" }, { name: "stand-count.jpg" }, { name: "storm-damage.jpg" }, ], }, { name: "crop-plan-2026.pdf" }, { name: "yield-summary.xlsx" }, { name: "rainfall-log.csv" }, { name: "equipment-list.pdf" }, { name: "applicator-license.pdf" }, { name: "price-sheet.pdf" }, { name: "archive.zip" }, ];
function renderItem(fileItem: FileTreeItem) { if ("items" in fileItem) { return ( <Collapsible key={fileItem.name}> <CollapsibleTrigger render={ <Button variant="ghost" size="sm" className="tw:group tw:w-full tw:justify-start tw:transition-none tw:hover:bg-accent tw:hover:text-accent-foreground" /> } > <ChevronRightIcon className="tw:transition-transform tw:group-data-panel-open:rotate-90" /> <FolderIcon /> {fileItem.name} </CollapsibleTrigger> <CollapsibleContent className="tw:mt-1 tw:ml-5"> <div className="tw:flex tw:flex-col tw:gap-1"> {fileItem.items.map((child) => renderItem(child))} </div> </CollapsibleContent> </Collapsible> ); } return ( <Button key={fileItem.name} variant="link" size="sm" className="tw:w-full tw:justify-start tw:gap-2 tw:text-foreground" > <FileIcon /> <span>{fileItem.name}</span> </Button> ); }
return ( <Card className="tw:mx-auto tw:w-full tw:max-w-[16rem] tw:gap-2" size="sm"> <CardHeader> <Tabs defaultValue="documents"> <TabsList className="tw:w-full"> <TabsTrigger value="documents">Documents</TabsTrigger> <TabsTrigger value="recent">Recent</TabsTrigger> </TabsList> </Tabs> </CardHeader> <CardContent> <div className="tw:flex tw:flex-col tw:gap-1"> {fileTree.map((item) => renderItem(item))} </div> </CardContent> </Card> );}Collapsible
Section titled “Collapsible”Groups a trigger with its content panel. Renders a <div> element.
className
Section titled “className”className?: stringCSS class applied to the collapsible root.
defaultOpen
Section titled “defaultOpen”defaultOpen?: booleanWhether the panel is initially open. Use open when controlled.
disabled
Section titled “disabled”disabled?: booleanWhether the collapsible ignores user interaction.
onOpenChange
Section titled “onOpenChange”onOpenChange?: ((open: boolean, eventDetails: CollapsibleRootChangeEventDetails) => void)Called when the panel opens or closes.
open?: booleanWhether the panel is currently open. Use defaultOpen when uncontrolled.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, CollapsibleRootState>Allows replacing the root element or composing it with another component.
style?: React.CSSProperties | ((state: CollapsibleRootState) => React.CSSProperties | undefined)Style applied to the collapsible root.
CollapsibleContent
Section titled “CollapsibleContent”Contains the collapsible content. Renders a <div> element.
className
Section titled “className”className?: stringCSS class applied to the content panel.
hiddenUntilFound
Section titled “hiddenUntilFound”hiddenUntilFound?: booleanAllow browser find-in-page to reveal hidden content.
keepMounted
Section titled “keepMounted”keepMounted?: booleanKeep the content panel mounted while it is closed. Ignored when
hiddenUntilFound is set.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, CollapsiblePanelState>Allows replacing the panel element or composing it with another component.
style?: React.CSSProperties | ((state: CollapsiblePanelState) => React.CSSProperties | undefined)Style applied to the content panel.
CollapsibleTrigger
Section titled “CollapsibleTrigger”Opens and closes the content panel. Renders a <button> element.
className
Section titled “className”className?: stringCSS class applied to the trigger.
nativeButton
Section titled “nativeButton”nativeButton?: booleanWhether render returns a native button. Set to false for another
element.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, CollapsibleTriggerState>Allows replacing the trigger element or composing it with another component.
style?: React.CSSProperties | ((state: CollapsibleTriggerState) => React.CSSProperties | undefined)Style applied to the trigger.