Accordion
A vertically stacked set of interactive headings that each reveal a section of content.
Code
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "@falcon/ui-kit";
export function Example() { return ( <Accordion defaultValue={["delivery"]} className="tw:max-w-lg"> <AccordionItem value="delivery"> <AccordionTrigger>What are your delivery options?</AccordionTrigger> <AccordionContent> We offer scheduled farm delivery (2-3 days), branch pickup (same day), and direct ship from suppliers. Free delivery on bulk orders. </AccordionContent> </AccordionItem> <AccordionItem value="returns"> <AccordionTrigger>What is your return policy?</AccordionTrigger> <AccordionContent> Returns accepted within 30 days. Products must be unopened and in original packaging. Credits are applied to your account within 5-7 business days. </AccordionContent> </AccordionItem> <AccordionItem value="support"> <AccordionTrigger>How can I contact customer support?</AccordionTrigger> <AccordionContent> Reach your account team via email, live chat, or phone. We respond within 24 hours during business days. </AccordionContent> </AccordionItem> </Accordion> );}Composition
Section titled “Composition”Use the following composition to build an Accordion:
Accordion├── AccordionItem│ ├── AccordionTrigger│ └── AccordionContent└── AccordionItem ├── AccordionTrigger └── AccordionContentA basic accordion that shows one item at a time. The first item is open by default.
Code
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "@falcon/ui-kit";
const items = [ { value: "item-1", trigger: "How do I reset my password?", content: "Click on 'Forgot Password' on the login page, enter your email address, and we'll send you a link to reset your password. The link will expire in 24 hours.", }, { value: "item-2", trigger: "Can I change an order after it is placed?", content: "Yes, you can update quantities or products on an open order at any time from your orders page. Changes will be reflected on your next invoice.", }, { value: "item-3", trigger: "What payment methods do you accept?", content: "We accept all major credit cards, ACH transfers, and checks. All payments are processed securely through our payment partners.", },];
export function Example() { return ( <Accordion defaultValue={["item-1"]} className="tw:max-w-lg"> {items.map((item) => ( <AccordionItem key={item.value} value={item.value}> <AccordionTrigger>{item.trigger}</AccordionTrigger> <AccordionContent>{item.content}</AccordionContent> </AccordionItem> ))} </Accordion> );}Multiple
Section titled “Multiple”Use the multiple prop to allow multiple items to be open at the same time.
Code
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "@falcon/ui-kit";
const items = [ { value: "notifications", trigger: "Notification Settings", content: "Manage how you receive notifications. You can enable email alerts for order updates or push notifications for mobile devices.", }, { value: "privacy", trigger: "Privacy & Security", content: "Control your privacy settings and security preferences. Enable two-factor authentication, manage connected devices, review active sessions, and configure data sharing preferences. You can also download your data or delete your account.", }, { value: "billing", trigger: "Billing & Statements", content: "View your account balance, payment history, and upcoming invoices. Update your payment method, download monthly statements, or enroll in prepay.", },];
export function Example() { return ( <Accordion multiple className="tw:max-w-lg" defaultValue={["notifications"]} > {items.map((item) => ( <AccordionItem key={item.value} value={item.value}> <AccordionTrigger>{item.trigger}</AccordionTrigger> <AccordionContent>{item.content}</AccordionContent> </AccordionItem> ))} </Accordion> );}Disabled
Section titled “Disabled”Use the disabled prop on AccordionItem to disable individual items.
Code
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "@falcon/ui-kit";
export function Example() { return ( <Accordion className="tw:w-full"> <AccordionItem value="item-1"> <AccordionTrigger>Can I access my order history?</AccordionTrigger> <AccordionContent> Yes, you can view your complete order history including all invoices, deliveries, and support tickets in the Order History section of your dashboard. </AccordionContent> </AccordionItem> <AccordionItem value="item-2" disabled> <AccordionTrigger>Prepay balance information</AccordionTrigger> <AccordionContent> This section contains information about prepay balances. Contact your retailer to enable prepay on this account. </AccordionContent> </AccordionItem> <AccordionItem value="item-3"> <AccordionTrigger>How do I update my email address?</AccordionTrigger> <AccordionContent> You can update your email address in your account settings. You'll receive a verification email at your new address to confirm the change. </AccordionContent> </AccordionItem> </Accordion> );}Borders
Section titled “Borders”Add tw:border to the Accordion and tw:border-b tw:last:border-b-0 to the
AccordionItem to add borders to the items.
Code
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "@falcon/ui-kit";
const items = [ { value: "billing", trigger: "How does billing work?", content: "We offer monthly statements and prepay accounts. Invoices are issued at delivery, and you can pay by check, ACH, or card. All accounts include itemized invoices, season-end summaries, and shared access for farm partners.", }, { value: "security", trigger: "Is my data secure?", content: "Yes. We use end-to-end encryption, SOC 2 Type II compliance, and regular third-party security audits. All data is encrypted at rest and in transit using industry-standard protocols.", }, { value: "integration", trigger: "What integrations do you support?", content: "We integrate with popular agronomy, accounting, and farm management tools. You can also build custom integrations using our REST API and webhooks.", },];
export function Example() { return ( <Accordion className="tw:max-w-lg tw:rounded-lg tw:border" defaultValue={["billing"]} > {items.map((item) => ( <AccordionItem key={item.value} value={item.value} className="tw:border-b tw:px-4 tw:last:border-b-0" > <AccordionTrigger>{item.trigger}</AccordionTrigger> <AccordionContent>{item.content}</AccordionContent> </AccordionItem> ))} </Accordion> );}Wrap the Accordion in a Card component.
Code
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Card, CardContent, CardDescription, CardHeader, CardTitle,} from "@falcon/ui-kit";
const items = [ { value: "financing", trigger: "What financing options do you offer?", content: "We offer standard terms (net 30), seasonal financing, and prepay discounts. Each option includes different rates and due dates based on your account standing.", }, { value: "billing", trigger: "How does billing work?", content: "Invoices are issued automatically when orders are delivered. We accept checks, ACH transfers, and all major credit cards. You'll receive an invoice via email after each delivery.", }, { value: "cancel", trigger: "How do I cancel an order?", content: "You can cancel an open order anytime from your orders page. There are no cancellation fees before fulfillment. Allocated product is returned to inventory when you cancel.", },];
export function Example() { return ( <Card className="tw:w-full tw:max-w-sm"> <CardHeader> <CardTitle>Billing & Payments</CardTitle> <CardDescription> Common questions about your account, financing, payments and cancellations. </CardDescription> </CardHeader> <CardContent> <Accordion defaultValue={["financing"]}> {items.map((item) => ( <AccordionItem key={item.value} value={item.value}> <AccordionTrigger>{item.trigger}</AccordionTrigger> <AccordionContent>{item.content}</AccordionContent> </AccordionItem> ))} </Accordion> </CardContent> </Card> );}Accordion
Section titled “Accordion”Groups all parts of the accordion. Renders a <div> element and accepts
standard <div> props. Use render to replace the element. Items are always
stacked vertically, and arrow-key navigation wraps from the last trigger back
to the first.
className
Section titled “className”className?: stringCSS class applied to the element.
defaultValue
Section titled “defaultValue”defaultValue?: AccordionValue<TValue>The uncontrolled value of the item(s) that should be initially expanded. To
render a controlled accordion, use the value prop instead.
disabled
Section titled “disabled”disabled?: booleanWhether the component should ignore user interaction.
hiddenUntilFound
Section titled “hiddenUntilFound”hiddenUntilFound?: booleanAllows the browser’s built-in page search to find and expand the panel
contents. Overrides the keepMounted prop and uses hidden="until-found"
to hide the element without removing it from the DOM.
keepMounted
Section titled “keepMounted”keepMounted?: booleanWhether to keep the element in the DOM while the panel is closed. This prop
is ignored when hiddenUntilFound is used.
multiple
Section titled “multiple”multiple?: booleanWhether multiple items can be open at the same time.
onValueChange
Section titled “onValueChange”onValueChange?: ((value: AccordionValue<TValue>, eventDetails: AccordionRootChangeEventDetails) => void)Event handler called when an accordion item is expanded or collapsed. Provides the new value as an argument.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionPrimitive.Root.State<TValue>>Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a React element or a function that returns the element to render.
style?: React.CSSProperties | ((state: AccordionPrimitive.Root.State<TValue>) => React.CSSProperties | undefined)Style applied to the element, or a function that returns a style object based on the component’s state.
value?: AccordionValue<TValue>The controlled value of the item(s) that should be expanded. To render an
uncontrolled accordion, use the defaultValue prop instead.
AccordionContent
Section titled “AccordionContent”A collapsible panel with the accordion item contents. Renders a <div>
element and accepts standard <div> props. Use render to replace the outer
panel element. Its className applies to the inner content wrapper. Pair it
with AccordionTrigger in an AccordionItem.
className
Section titled “className”className?: stringCSS class applied to the inner content wrapper.
hiddenUntilFound
Section titled “hiddenUntilFound”hiddenUntilFound?: booleanAllows the browser’s built-in page search to find and expand the panel
contents. Overrides the keepMounted prop and uses hidden="until-found"
to hide the element without removing it from the DOM.
keepMounted
Section titled “keepMounted”keepMounted?: booleanWhether to keep the element in the DOM while the panel is closed. This prop
is ignored when hiddenUntilFound is used.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionPanelState>Allows you to replace the outer panel element with a different tag, or
compose it with another component. Accepts a React element or a function
that returns the element to render. The className prop still applies to
the inner content wrapper.
style?: React.CSSProperties | ((state: AccordionPanelState) => React.CSSProperties | undefined)Style applied to the element, or a function that returns a style object based on the component’s state.
AccordionItem
Section titled “AccordionItem”Groups an accordion header with the corresponding panel. Renders a <div>
element and accepts standard <div> props. Use render to replace the
element.
className
Section titled “className”className?: stringCSS class applied to the element.
disabled
Section titled “disabled”disabled?: booleanWhether the component should ignore user interaction.
onOpenChange
Section titled “onOpenChange”onOpenChange?: ((open: boolean, eventDetails: AccordionPrimitive.Item.ChangeEventDetails) => void)Event handler called when the panel is opened or closed.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionItemState>Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a React element or a function that returns the element to render.
style?: React.CSSProperties | ((state: AccordionItemState) => React.CSSProperties | undefined)Style applied to the element, or a function that returns a style object based on the component’s state.
value?: anyA unique value that identifies this accordion item. If no value is provided, a unique ID is generated automatically. Use when controlling the accordion programmatically or setting an initial open state.
AccordionTrigger
Section titled “AccordionTrigger”A button that opens and closes the corresponding panel. Renders a <button>
element wrapped in a heading and accepts standard <button> props. Use
render to replace the element. Pair it with AccordionContent in an
AccordionItem. When using render or nativeButton={false}, provide an
accessible interactive control and trigger label. The trigger includes its
own decorative expand and collapse icon.
className
Section titled “className”className?: stringCSS class applied to the element.
nativeButton
Section titled “nativeButton”nativeButton?: boolean = trueWhether the component renders a native <button> element when replacing it
via the render prop. Set to false if the rendered element is not a
button.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionTriggerState>Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a React element or a function that returns the element to render.
style?: React.CSSProperties | ((state: AccordionTriggerState) => React.CSSProperties | undefined)Style applied to the element, or a function that returns a style object based on the component’s state.