From 643fe98c3948e2a84f37de33c3a711d89dc074e8 Mon Sep 17 00:00:00 2001 From: Lars Hampe Date: Mon, 30 Sep 2024 23:20:40 +0200 Subject: [PATCH] feat(ui): add more components --- packages/ui/package.json | 1 + packages/ui/src/badge.tsx | 36 ++++++++++ packages/ui/src/card.tsx | 76 +++++++++++++++++++++ packages/ui/src/index.ts | 4 ++ packages/ui/src/input.tsx | 25 +++++++ packages/ui/src/sheet.tsx | 138 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 280 insertions(+) create mode 100644 packages/ui/src/badge.tsx create mode 100644 packages/ui/src/card.tsx create mode 100644 packages/ui/src/input.tsx create mode 100644 packages/ui/src/sheet.tsx diff --git a/packages/ui/package.json b/packages/ui/package.json index 0ee2fb5..ee48456 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-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", "class-variance-authority": "^0.7.0", diff --git a/packages/ui/src/badge.tsx b/packages/ui/src/badge.tsx new file mode 100644 index 0000000..125ccad --- /dev/null +++ b/packages/ui/src/badge.tsx @@ -0,0 +1,36 @@ +import { type VariantProps, cva } from 'class-variance-authority' +import type * as React from 'react' + +import { cn } from './lib/cn' + +const badgeVariants = cva( + 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', + { + variants: { + variant: { + default: + 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80', + secondary: + 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', + destructive: + 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80', + outline: 'text-foreground', + }, + }, + defaultVariants: { + variant: 'default', + }, + }, +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/packages/ui/src/card.tsx b/packages/ui/src/card.tsx new file mode 100644 index 0000000..6322217 --- /dev/null +++ b/packages/ui/src/card.tsx @@ -0,0 +1,76 @@ +import * as React from 'react' + +import { cn } from './lib/cn' + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = 'Card' + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = 'CardHeader' + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = 'CardTitle' + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = 'CardDescription' + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = 'CardContent' + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = 'CardFooter' + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index b57a040..8ea7742 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -3,3 +3,7 @@ export * from './theme-provider' export * from './theme-toggle' export * from './button' export * from './dropdown-menu' +export * from './badge' +export * from './card' +export * from './input' +export * from './sheet' diff --git a/packages/ui/src/input.tsx b/packages/ui/src/input.tsx new file mode 100644 index 0000000..e75d595 --- /dev/null +++ b/packages/ui/src/input.tsx @@ -0,0 +1,25 @@ +import * as React from 'react' + +import { cn } from './lib/cn' + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + }, +) +Input.displayName = 'Input' + +export { Input } diff --git a/packages/ui/src/sheet.tsx b/packages/ui/src/sheet.tsx new file mode 100644 index 0000000..0cdb1a0 --- /dev/null +++ b/packages/ui/src/sheet.tsx @@ -0,0 +1,138 @@ +import * as SheetPrimitive from '@radix-ui/react-dialog' +import { type VariantProps, cva } from 'class-variance-authority' +import { XIcon } from 'lucide-react' +import * as React from 'react' + +import { cn } from './lib/cn' + +const Sheet = SheetPrimitive.Root + +const SheetTrigger = SheetPrimitive.Trigger + +const SheetClose = SheetPrimitive.Close + +const SheetPortal = SheetPrimitive.Portal + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName + +const sheetVariants = cva( + 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out', + { + variants: { + side: { + top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top', + bottom: + 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom', + left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm', + right: + 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm', + }, + }, + defaultVariants: { + side: 'right', + }, + }, +) + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = 'right', className, children, ...props }, ref) => ( + + + + + + Close + + {children} + + +)) +SheetContent.displayName = SheetPrimitive.Content.displayName + +const SheetHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetHeader.displayName = 'SheetHeader' + +const SheetFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetFooter.displayName = 'SheetFooter' + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetTitle.displayName = SheetPrimitive.Title.displayName + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetDescription.displayName = SheetPrimitive.Description.displayName + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +}