Search for a command to run...
A vertically stacked set of interactive headings that each reveal a section of content.
npx shadcn@latest add @zaidan/accordionpnpx shadcn add @zaidan/accordionyarn dlx shadcn@latest add @zaidan/accordionbunx shadcn@latest add @zaidan/accordionCopy and paste the following code into your project.
1import * as AccordionPrimitive from "@kobalte/core/accordion";2import type { PolymorphicProps } from "@kobalte/core/polymorphic";3import { ChevronDown } from "lucide-solid";4import type { ComponentProps, ValidComponent } from "solid-js";5import { splitProps } from "solid-js";6
7import { cn } from "~/lib/utils";8
9type AccordionProps<T extends ValidComponent = "div"> = PolymorphicProps<10 T,11 AccordionPrimitive.AccordionRootProps<T>12> &13 Pick<ComponentProps<T>, "class">;14
15const Accordion = <T extends ValidComponent = "div">(props: AccordionProps<T>) => {16 const [local, others] = splitProps(props as AccordionProps, ["class"]);17 return (18 <AccordionPrimitive.Root19 class={cn("z-accordion flex w-full flex-col", local.class)}20 data-slot="accordion"21 {...others}22 />23 );24};25
26type AccordionItemProps<T extends ValidComponent = "div"> = PolymorphicProps<27 T,28 AccordionPrimitive.AccordionItemProps<T>29> &30 Pick<ComponentProps<T>, "class">;31
32const AccordionItem = <T extends ValidComponent = "div">(props: AccordionItemProps<T>) => {33 const [local, others] = splitProps(props as AccordionItemProps, ["class"]);34 return (35 <AccordionPrimitive.Item36 class={cn("z-accordion-item", local.class)}37 data-slot="accordion-item"38 {...others}39 />40 );41};42
43type AccordionTriggerProps<T extends ValidComponent = "button"> = PolymorphicProps<44 T,45 AccordionPrimitive.AccordionTriggerProps<T>46> &47 Pick<ComponentProps<T>, "class" | "children">;48
49const AccordionTrigger = <T extends ValidComponent = "button">(props: AccordionTriggerProps<T>) => {50 const [local, others] = splitProps(props as AccordionTriggerProps, ["class", "children"]);51 return (52 <AccordionPrimitive.Header class="flex" data-slot="accordion-header">53 <AccordionPrimitive.Trigger54 class={cn(55 "group/accordion-trigger relative z-accordion-trigger flex flex-1 items-start justify-between border border-transparent outline-none transition-all disabled:pointer-events-none disabled:opacity-50",56 local.class,57 )}58 data-slot="accordion-trigger"59 {...others}60 >61 {local.children}62 <ChevronDown63 class="pointer-events-none z-accordion-trigger-icon shrink-0 duration-300 group-aria-expanded/accordion-trigger:rotate-180"64 data-slot="accordion-trigger-icon"65 />66 </AccordionPrimitive.Trigger>67 </AccordionPrimitive.Header>68 );69};70
71type AccordionContentProps<T extends ValidComponent = "div"> = PolymorphicProps<72 T,73 AccordionPrimitive.AccordionContentProps<T>74> &75 Pick<ComponentProps<T>, "class" | "children">;76
77const AccordionContent = <T extends ValidComponent = "div">(props: AccordionContentProps<T>) => {78 const [local, others] = splitProps(props as AccordionContentProps, ["class", "children"]);79 return (80 <AccordionPrimitive.Content81 class="z-accordion-content overflow-hidden"82 data-slot="accordion-content"83 {...others}84 >85 <div86 class={cn(87 "z-accordion-content-inner h-(--kb-collapsible-content-height) [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",88 local.class,89 )}90 data-slot="accordion-content-inner"91 >92 {local.children}93 </div>94 </AccordionPrimitive.Content>95 );96};97
98export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };Here are the source code of all the examples from the preview page:
import { For } from "solid-js";import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion";function AccordionBasic() { const items = [ { value: "item-1", trigger: "Is it accessible?", content: "Yes. It adheres to the WAI-ARIA design pattern.", }, { value: "item-2", trigger: "Is it styled?", content: "Yes. It comes with default styles that matches the other components' aesthetic.", }, { value: "item-3", trigger: "Is it animated?", content: "Yes. It's animated by default, but you can disable it if you prefer.", }, ];
return ( <Example title="Basic"> <Accordion class="mx-auto max-w-lg"> <For each={items}> {(item) => ( <AccordionItem value={item.value}> <AccordionTrigger>{item.trigger}</AccordionTrigger> <AccordionContent>{item.content}</AccordionContent> </AccordionItem> )} </For> </Accordion> </Example> );}import { For } from "solid-js";import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion";function AccordionMultiple() { const items = [ { value: "item-1", trigger: "What are the key considerations when implementing a comprehensive enterprise-level authentication system?", content: "Implementing a robust enterprise authentication system requires careful consideration of multiple factors. This includes secure password hashing and storage, multi-factor authentication (MFA) implementation, session management, OAuth2 and SSO integration, regular security audits, rate limiting to prevent brute force attacks, and maintaining detailed audit logs. Additionally, you'll need to consider scalability, performance impact, and compliance with relevant data protection regulations such as GDPR or HIPAA.", }, { value: "item-2", trigger: "How does modern distributed system architecture handle eventual consistency and data synchronization across multiple regions?", content: "Modern distributed systems employ various strategies to maintain data consistency across regions. This often involves using techniques like CRDT (Conflict-Free Replicated Data Types), vector clocks, and gossip protocols. Systems might implement event sourcing patterns, utilize message queues for asynchronous updates, and employ sophisticated conflict resolution strategies. Popular solutions like Amazon's DynamoDB and Google's Spanner demonstrate different approaches to solving these challenges, balancing between consistency, availability, and partition tolerance as described in the CAP theorem.", }, ];
return ( <Example title="Multiple"> <Accordion multiple class="mx-auto max-w-lg"> <For each={items}> {(item) => ( <AccordionItem value={item.value}> <AccordionTrigger>{item.trigger}</AccordionTrigger> <AccordionContent>{item.content}</AccordionContent> </AccordionItem> )} </For> </Accordion> </Example> );}import { For } from "solid-js";import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion";function AccordionWithBorders() { return ( <Example title="With Borders"> <Accordion class="mx-auto max-w-lg style-lyra:gap-2 style-nova:gap-2 style-vega:gap-2"> <AccordionItem value="billing" class="style-nova:rounded-lg style-vega:rounded-lg style-lyra:border style-nova:border style-vega:border" > <AccordionTrigger class="style-lyra:px-2 style-nova:px-2.5 style-vega:px-4 font-medium style-lyra:text-xs style-maia:text-sm style-mira:text-xs style-nova:text-sm style-vega:text-sm"> How does billing work? </AccordionTrigger> <AccordionContent class="style-lyra:px-2 style-maia:px-0 style-mira:px-0 style-nova:px-2.5 style-vega:px-4 style-lyra:text-xs style-nova:text-sm text-muted-foreground"> We offer monthly and annual subscription plans. Billing is charged at the beginning of each cycle, and you can cancel anytime. All plans include automatic backups, 24/7 support, and unlimited team members. There are no hidden fees or setup costs. </AccordionContent> </AccordionItem> <AccordionItem value="security" class="style-nova:rounded-lg style-vega:rounded-lg style-lyra:border style-nova:border style-vega:border" > <AccordionTrigger class="style-lyra:px-2 style-nova:px-2.5 style-vega:px-4 font-medium style-lyra:text-xs style-maia:text-sm style-mira:text-xs style-nova:text-sm style-vega:text-sm"> Is my data secure? </AccordionTrigger> <AccordionContent class="style-lyra:px-2 style-maia:px-0 style-mira:px-0 style-nova:px-2.5 style-vega:px-4 style-lyra:text-xs style-nova:text-sm text-muted-foreground"> 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. We also offer optional two-factor authentication and single sign-on for enterprise customers. </AccordionContent> </AccordionItem> <AccordionItem value="integration" class="style-nova:rounded-lg style-vega:rounded-lg style-lyra:border style-nova:border style-vega:border" > <AccordionTrigger class="style-lyra:px-2 style-nova:px-2.5 style-vega:px-4 font-medium style-lyra:text-xs style-maia:text-sm style-mira:text-xs style-nova:text-sm style-vega:text-sm"> What integrations do you support? </AccordionTrigger> <AccordionContent class="style-lyra:px-2 style-maia:px-0 style-mira:px-0 style-nova:px-2.5 style-vega:px-4 style-lyra:text-xs style-nova:text-sm text-muted-foreground"> <p> We integrate with 500+ popular tools including Slack, Zapier, Salesforce, HubSpot, and more. You can also build custom integrations using our REST API and webhooks. </p> <p>Our API documentation includes code examples in 10+ programming languages.</p> </AccordionContent> </AccordionItem> </Accordion> </Example> );}import { ArrowUpRight } from "lucide-solid";import { For } from "solid-js";import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion";import { Button } from "~/components/ui/button";import { Card, CardContent, CardDescription, CardHeader, CardTitle,} from "~/components/ui/card";function AccordionInCard() { return ( <Example title="In Card"> <Card class="mx-auto w-full max-w-lg gap-4"> <CardHeader> <CardTitle>Subscription & Billing</CardTitle> <CardDescription> Common questions about your account, plans, and payments </CardDescription> </CardHeader> <CardContent> <Accordion multiple defaultValue={["plans"]} class="style-maia:rounded-md style-mira:rounded-md" > <AccordionItem value="plans"> <AccordionTrigger>What subscription plans do you offer?</AccordionTrigger> <AccordionContent> <p> We offer three subscription tiers: Starter ($9/month), Professional ($29/month), and Enterprise ($99/month). Each plan includes increasing storage limits, API access, priority support, and team collaboration features. </p> <p> <a href="#">Annual billing is available</a> with a 20% discount. All plans include a 14-day free trial with no credit card required. </p> <Button size="sm"> View plans <ArrowUpRight /> </Button> </AccordionContent> </AccordionItem> <AccordionItem value="billing"> <AccordionTrigger>How does billing work?</AccordionTrigger> <AccordionContent> <p> Billing occurs automatically at the start of each billing cycle. We accept all major credit cards, PayPal, and ACH transfers for enterprise customers. </p> <p> You'll receive an invoice via email after each payment. You can update your payment method or billing information anytime in your account settings. Failed payments will trigger automated retry attempts and email notifications. </p> </AccordionContent> </AccordionItem> <AccordionItem value="upgrade"> <AccordionTrigger>Can I upgrade or downgrade my plan?</AccordionTrigger> <AccordionContent> <p> Yes, you can change your plan at any time. When upgrading, you'll be charged a prorated amount for the remainder of your billing cycle and immediately gain access to new features. </p> <p> When downgrading, the change takes effect at the end of your current billing period, and you'll retain access to premium features until then. No refunds are provided for downgrades. </p> </AccordionContent> </AccordionItem> <AccordionItem value="cancel"> <AccordionTrigger>How do I cancel my subscription?</AccordionTrigger> <AccordionContent> <p> You can cancel your subscription anytime from your account settings. There are no cancellation fees or penalties. Your access will continue until the end of your current billing period. </p> <p> After cancellation, your data is retained for 30 days in case you want to reactivate. You can export all your data before or after canceling. We'd love to hear your feedback about why you're leaving. </p> </AccordionContent> </AccordionItem> <AccordionItem value="refund"> <AccordionTrigger>What is your refund policy?</AccordionTrigger> <AccordionContent> <p> We offer a 30-day money-back guarantee for new subscriptions. If you're not satisfied within the first 30 days, contact our support team for a full refund. </p> <p> After 30 days, we don't provide refunds for partial billing periods, but you can cancel anytime to avoid future charges. Enterprise customers have custom refund terms outlined in their contracts. </p> </AccordionContent> </AccordionItem> </Accordion> </CardContent> </Card> </Example> );}import { For } from "solid-js";import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion";function AccordionWithDisabled() { const items = [ { value: "item-1", trigger: "Can I access my account history?", content: "Yes, you can view your complete account history including all transactions, plan changes, and support tickets in the Account History section of your dashboard.", disabled: false, }, { value: "item-2", trigger: "Premium feature information", content: "This section contains information about premium features. Upgrade your plan to access this content.", disabled: true, }, { value: "item-3", trigger: "How do I update my email address?", content: "You can update your email address in your account settings. You'll receive a verification email at your new address to confirm the change.", disabled: false, }, ];
return ( <Example title="With Disabled"> <Accordion class="mx-auto max-w-lg overflow-hidden style-lyra:rounded-none style-maia:rounded-lg style-mira:rounded-lg style-nova:rounded-lg style-vega:rounded-lg border"> <For each={items}> {(item) => ( <AccordionItem value={item.value} disabled={item.disabled} class="p-1 data-open:bg-muted/50" > <AccordionTrigger class="style-lyra:px-2 style-nova:px-2.5 style-vega:px-4"> {item.trigger} </AccordionTrigger> <AccordionContent class="style-lyra:px-2 style-nova:px-2.5 style-vega:px-4"> {item.content} </AccordionContent> </AccordionItem> )} </For> </Accordion> </Example> );}