import {
Accordion,
AccordionItem,
AccordionItemContent,
AccordionItemTrigger,
} from "@/components/ui/accordion"
export default function Component() {
return (
<Accordion collapsible defaultValue={["React"]} className="w-full">
<AccordionItem value="item-1">
<AccordionItemTrigger>Is it accessible?</AccordionItemTrigger>
<AccordionItemContent>
Yes. It adheres to the WAI-ARIA design pattern.
</AccordionItemContent>
</AccordionItem>{" "}
<AccordionItem value="item-2">
<AccordionItemTrigger>Is it styled?</AccordionItemTrigger>
<AccordionItemContent>
Yes. It comes with default styles that matches the other
components' aesthetic.
</AccordionItemContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionItemTrigger>Is it animated?</AccordionItemTrigger>
<AccordionItemContent>
Yes. It's animated by default, but you can disable it if you
prefer.
</AccordionItemContent>
</AccordionItem>
</Accordion>
)
}
Not supported yet
Not supported yet
Not supported yet
Installation
Copy and paste the following code into your project.
"use client"
import * as React from "react"
import { Accordion as AccordionPrimitive } from "@ark-ui/react/accordion"
import { ChevronDown } from "lucide-react"
import { cn } from "@/lib/utils"
const Accordion = AccordionPrimitive.Root
const AccordionContext = AccordionPrimitive.Context
const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
AccordionPrimitive.ItemProps
>(({ className, ...props }, ref) => (
<AccordionPrimitive.Item
ref={ref}
className={cn("border-b last:border-b-0", className)}
{...props}
/>
))
AccordionItem.displayName = "AccordionItem"
const AccordionItemContent = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.ItemContent>,
AccordionPrimitive.ItemContentProps
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.ItemContent
ref={ref}
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
{...props}
>
<div className={cn("pt-0 pb-4", className)}>{children}</div>
</AccordionPrimitive.ItemContent>
))
AccordionItemContent.displayName = "AccordionItemContent"
const AccordionItemContext = AccordionPrimitive.ItemContext
const AccordionItemTrigger = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.ItemTrigger>,
AccordionPrimitive.ItemTriggerProps
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.ItemTrigger
ref={ref}
className={cn(
"flex w-full flex-1 items-center justify-between gap-4 rounded-md py-4 text-left font-semibold text-sm outline-none transition-all hover:underline focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50",
className
)}
{...props}
>
{children}
<AccordionPrimitive.ItemIndicator className="[&[data-state=open]>svg]:rotate-180">
<ChevronDown className="pointer-events-none size-4 shrink-0 opacity-60 transition-transform duration-200" />
</AccordionPrimitive.ItemIndicator>
</AccordionPrimitive.ItemTrigger>
))
AccordionItemTrigger.displayName = "AccordionItemTrigger"
export {
Accordion,
AccordionContext,
AccordionItem,
AccordionItemContent,
AccordionItemContext,
AccordionItemTrigger,
}
AccordionItem.vue
<script setup lang="ts">
import { useForwardProps } from "@ark-ui/vue"
import { AccordionItem, type AccordionItemProps } from "@ark-ui/vue/accordion"
import { reactiveOmit } from "@vueuse/core"
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<
AccordionItemProps & { class?: HTMLAttributes["class"] }
>()
const delegatedProps = reactiveOmit(props, "class")
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<AccordionItem
v-bind="forwardedProps"
:class="cn('border-b last:border-b-0', props.class)"
>
<slot />
</AccordionItem>
</template>
AccordionItemContent.vue
<script setup lang="ts">
import {
AccordionItemContent,
type AccordionItemContentProps,
} from "@ark-ui/vue/accordion"
import { reactiveOmit } from "@vueuse/core"
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<
AccordionItemContentProps & { class?: HTMLAttributes["class"] }
>()
const delegatedProps = reactiveOmit(props, "class")
</script>
<template>
<AccordionItemContent
v-bind="delegatedProps"
class="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
>
<div :class="cn('pt-0 pb-4', props.class)">
<slot />
</div>
</AccordionItemContent>
</template>
AccordionItemTrigger.vue
<script setup lang="ts">
import {
AccordionItemIndicator,
AccordionItemTrigger,
type AccordionItemTriggerProps,
} from "@ark-ui/vue/accordion"
import { reactiveOmit } from "@vueuse/core"
import { ChevronDown } from "lucide-vue-next"
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<
AccordionItemTriggerProps & { class?: HTMLAttributes["class"] }
>()
const delegatedProps = reactiveOmit(props, "class")
</script>
<template>
<AccordionItemTrigger
v-bind="delegatedProps"
:class="cn('flex w-full flex-1 items-center justify-between gap-4 rounded-md py-4 text-left font-semibold text-sm outline-none transition-all hover:underline focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50', props.class)"
>
<slot />
<AccordionItemIndicator class="[&[data-state=open]>svg]:rotate-180">
<ChevronDown class="pointer-events-none size-4 shrink-0 opacity-60 transition-transform duration-200" />
</AccordionItemIndicator>
</AccordionItemTrigger>
</template>
index.ts
export {
AccordionRoot as Accordion,
AccordionContext,
AccordionItemContext,
} from "@ark-ui/vue/accordion"
export { default as AccordionItem } from "./AccordionItem.vue"
export { default as AccordionItemContent } from "./AccordionItemContent.vue"
export { default as AccordionItemTrigger } from "./AccordionItemTrigger.vue"
Not supported yet
Not supported yet
Update the import paths to match your project setup.
bunx --bun shadcn@latest add @shipbase/accordion
npx shadcn@latest add @shipbase/accordion
pnpm dlx shadcn@latest add @shipbase/accordion
yarn dlx shadcn@latest add @shipbase/accordion
Usage
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>
Yes. It adheres to the WAI-ARIA design pattern.
</AccordionContent>
</AccordionItem>
</Accordion>