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'