From 77b3b7d84a326751c62ffa95394e2ab37aeb4a90 Mon Sep 17 00:00:00 2001
From: Lars Hampe <hello@hashdot.co>
Date: Tue, 1 Oct 2024 11:01:50 +0200
Subject: [PATCH] feat(ui): add accordion component

---
 packages/ui/package.json      |  1 +
 packages/ui/src/accordion.tsx | 52 +++++++++++++++++++++++++++++++++++
 packages/ui/src/index.ts      |  1 +
 3 files changed, 54 insertions(+)
 create mode 100644 packages/ui/src/accordion.tsx

diff --git a/packages/ui/package.json b/packages/ui/package.json
index ee48456..1c5f2f1 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -5,6 +5,7 @@
   "type": "module",
   "main": "./src/index.ts",
   "dependencies": {
+    "@radix-ui/react-accordion": "^1.2.0",
     "@radix-ui/react-dialog": "^1.1.1",
     "@radix-ui/react-dropdown-menu": "^2.1.1",
     "@radix-ui/react-slot": "^1.1.0",
diff --git a/packages/ui/src/accordion.tsx b/packages/ui/src/accordion.tsx
new file mode 100644
index 0000000..1fd53c3
--- /dev/null
+++ b/packages/ui/src/accordion.tsx
@@ -0,0 +1,52 @@
+import * as AccordionPrimitive from '@radix-ui/react-accordion'
+import { ChevronDown } from 'lucide-react'
+import * as React from 'react'
+
+import { cn } from './lib/cn'
+
+const Accordion = AccordionPrimitive.Root
+
+const AccordionItem = React.forwardRef<
+  React.ElementRef<typeof AccordionPrimitive.Item>,
+  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
+>(({ className, ...props }, ref) => (
+  <AccordionPrimitive.Item ref={ref} className={cn(className)} {...props} />
+))
+AccordionItem.displayName = 'AccordionItem'
+
+const AccordionTrigger = React.forwardRef<
+  React.ElementRef<typeof AccordionPrimitive.Trigger>,
+  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
+>(({ className, children, ...props }, ref) => (
+  <AccordionPrimitive.Header className="flex">
+    <AccordionPrimitive.Trigger
+      ref={ref}
+      className={cn(
+        'flex flex-1 items-center justify-between py-4 font-medium transition-all [&[data-state=open]>svg]:rotate-180',
+        className,
+      )}
+      {...props}
+    >
+      {children}
+      <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
+    </AccordionPrimitive.Trigger>
+  </AccordionPrimitive.Header>
+))
+AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
+
+const AccordionContent = React.forwardRef<
+  React.ElementRef<typeof AccordionPrimitive.Content>,
+  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
+>(({ className, children, ...props }, ref) => (
+  <AccordionPrimitive.Content
+    ref={ref}
+    className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
+    {...props}
+  >
+    <div className={cn('pb-4 pt-0', className)}>{children}</div>
+  </AccordionPrimitive.Content>
+))
+
+AccordionContent.displayName = AccordionPrimitive.Content.displayName
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index 8ea7742..f6217e3 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -7,3 +7,4 @@ export * from './badge'
 export * from './card'
 export * from './input'
 export * from './sheet'
+export * from './accordion'