eny.space Landingpage
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(app): add button component

Sam Sauer 692cc0d0 39ce1bbd

+101 -4
+62
app/actions/components/ui/button.tsx
··· 1 + import * as React from "react" 2 + import { Slot } from "@radix-ui/react-slot" 3 + import { cva, type VariantProps } from "class-variance-authority" 4 + 5 + import { cn } from "@/actions/lib/utils" 6 + 7 + const buttonVariants = cva( 8 + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", 9 + { 10 + variants: { 11 + variant: { 12 + default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 + destructive: 14 + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", 15 + outline: 16 + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", 17 + secondary: 18 + "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 + ghost: 20 + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", 21 + link: "text-primary underline-offset-4 hover:underline", 22 + }, 23 + size: { 24 + default: "h-9 px-4 py-2 has-[>svg]:px-3", 25 + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", 26 + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", 27 + icon: "size-9", 28 + "icon-sm": "size-8", 29 + "icon-lg": "size-10", 30 + }, 31 + }, 32 + defaultVariants: { 33 + variant: "default", 34 + size: "default", 35 + }, 36 + } 37 + ) 38 + 39 + function Button({ 40 + className, 41 + variant = "default", 42 + size = "default", 43 + asChild = false, 44 + ...props 45 + }: React.ComponentProps<"button"> & 46 + VariantProps<typeof buttonVariants> & { 47 + asChild?: boolean 48 + }) { 49 + const Comp = asChild ? Slot : "button" 50 + 51 + return ( 52 + <Comp 53 + data-slot="button" 54 + data-variant={variant} 55 + data-size={size} 56 + className={cn(buttonVariants({ variant, size, className }))} 57 + {...props} 58 + /> 59 + ) 60 + } 61 + 62 + export { Button, buttonVariants }
+38 -4
package-lock.json
··· 5 5 "packages": { 6 6 "": { 7 7 "dependencies": { 8 + "@radix-ui/react-slot": "^1.2.4", 8 9 "@stripe/react-stripe-js": "2.4.0", 9 10 "@stripe/stripe-js": "2.2.2", 10 11 "@tailwindcss/postcss": "^4.1.18", ··· 696 697 "node": ">= 10" 697 698 } 698 699 }, 700 + "node_modules/@radix-ui/react-compose-refs": { 701 + "version": "1.1.2", 702 + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", 703 + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", 704 + "license": "MIT", 705 + "peerDependencies": { 706 + "@types/react": "*", 707 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 708 + }, 709 + "peerDependenciesMeta": { 710 + "@types/react": { 711 + "optional": true 712 + } 713 + } 714 + }, 715 + "node_modules/@radix-ui/react-slot": { 716 + "version": "1.2.4", 717 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", 718 + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", 719 + "license": "MIT", 720 + "dependencies": { 721 + "@radix-ui/react-compose-refs": "1.1.2" 722 + }, 723 + "peerDependencies": { 724 + "@types/react": "*", 725 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 726 + }, 727 + "peerDependenciesMeta": { 728 + "@types/react": { 729 + "optional": true 730 + } 731 + } 732 + }, 699 733 "node_modules/@stripe/react-stripe-js": { 700 734 "version": "2.4.0", 701 735 "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-2.4.0.tgz", ··· 991 1025 "version": "15.7.15", 992 1026 "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", 993 1027 "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", 994 - "dev": true, 1028 + "devOptional": true, 995 1029 "license": "MIT" 996 1030 }, 997 1031 "node_modules/@types/react": { 998 1032 "version": "18.2.8", 999 1033 "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.8.tgz", 1000 1034 "integrity": "sha512-lTyWUNrd8ntVkqycEEplasWy2OxNlShj3zqS0LuB1ENUGis5HodmhM7DtCoUGbxj3VW/WsGA0DUhpG6XrM7gPA==", 1001 - "dev": true, 1035 + "devOptional": true, 1002 1036 "license": "MIT", 1003 1037 "dependencies": { 1004 1038 "@types/prop-types": "*", ··· 1010 1044 "version": "0.26.0", 1011 1045 "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.26.0.tgz", 1012 1046 "integrity": "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==", 1013 - "dev": true, 1047 + "devOptional": true, 1014 1048 "license": "MIT" 1015 1049 }, 1016 1050 "node_modules/@vercel/analytics": { ··· 1165 1199 "version": "3.2.3", 1166 1200 "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", 1167 1201 "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", 1168 - "dev": true, 1202 + "devOptional": true, 1169 1203 "license": "MIT" 1170 1204 }, 1171 1205 "node_modules/detect-libc": {
+1
package.json
··· 6 6 "start": "next start" 7 7 }, 8 8 "dependencies": { 9 + "@radix-ui/react-slot": "^1.2.4", 9 10 "@stripe/react-stripe-js": "2.4.0", 10 11 "@stripe/stripe-js": "2.2.2", 11 12 "@tailwindcss/postcss": "^4.1.18",