{"id":13810094,"url":"https://github.com/jakobhoeg/enhanced-button","last_synced_at":"2025-04-05T12:04:03.905Z","repository":{"id":220730728,"uuid":"751478104","full_name":"jakobhoeg/enhanced-button","owner":"jakobhoeg","description":"An enhanced version of the default shadcn-button component ","archived":false,"fork":false,"pushed_at":"2024-02-13T17:15:09.000Z","size":6631,"stargazers_count":435,"open_issues_count":1,"forks_count":15,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-18T19:37:53.875Z","etag":null,"topics":["button","component","component-library","nextjs","nextjs13","nextjs14","shadcn","shadcn-ui","shadcn-ui-button","typescript","ui-component","ui-library"],"latest_commit_sha":null,"homepage":"https://enhanced-button.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jakobhoeg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-01T17:31:31.000Z","updated_at":"2024-10-15T19:28:07.000Z","dependencies_parsed_at":"2024-08-04T02:03:08.115Z","dependency_job_id":"8c71bce5-a92f-439a-a3dd-ae22f665b76d","html_url":"https://github.com/jakobhoeg/enhanced-button","commit_stats":null,"previous_names":["jakobhoeg/enhanced-button"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhoeg%2Fenhanced-button","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhoeg%2Fenhanced-button/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhoeg%2Fenhanced-button/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakobhoeg%2Fenhanced-button/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jakobhoeg","download_url":"https://codeload.github.com/jakobhoeg/enhanced-button/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332560,"owners_count":20921853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["button","component","component-library","nextjs","nextjs13","nextjs14","shadcn","shadcn-ui","shadcn-ui-button","typescript","ui-component","ui-library"],"created_at":"2024-08-04T02:00:45.374Z","updated_at":"2025-04-05T12:04:03.882Z","avatar_url":"https://github.com/jakobhoeg.png","language":"TypeScript","funding_links":[],"categories":["一、核心组件与扩展库","Libs and Components","Components","TypeScript","Components \u0026 Libraries"],"sub_categories":["1. 基础组件增强"],"readme":"[\u003cimg src=\"ezgif-7-38e5f4fe19.gif\"\u003e](https://enhanced-button.vercel.app/)\n\n# enhanced-button\n\nAn enhanced version of the default **shadcn-button** component.\n\nExpands the default component by adding new beautiful button styles and features with minimal code, so you no longer have to create and manage multiple button components for your projects.\n\n[Demo](https://enhanced-button.vercel.app/) • [Preview](#Preview) • [Requisites](#Requisites) • [Installation](#Installation) • [Usage](#Usage)\n\n# Preview\n\nhttps://github.com/jakobhoeg/enhanced-button/assets/114422072/ee05475f-6502-4e7a-8bde-ae5144ece85e\n\n# Requisites\n\n[shadcn-ui](https://ui.shadcn.com/docs/installation) and [shadcn-ui button component](https://ui.shadcn.com/docs/components/button) must be installed in your project.\n\n# Installation\n\nAll it takes is **two** copy \u0026 paste and you're ready to go.\n\n**_1. Copy the `button.tsx` component below and replace it with your existing one in `src/components/ui/button.tsx`_**\n\n**_2. Copy the lines from `tailwind.config.ts` to your existing file._**\n\n\u003cdetails\u003e\n  \u003csummary\u003ebutton.tsx\u003c/summary\u003e\n\n```tsx\nimport * as React from 'react';\nimport { Slot, Slottable } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\n\nconst buttonVariants = cva(\n  'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [\u0026_svg]:pointer-events-none [\u0026_svg]:size-4 [\u0026_svg]:shrink-0',\n  {\n    variants: {\n      variant: {\n        default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n        destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n        outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n        ghost: 'hover:bg-accent hover:text-accent-foreground',\n        link: 'text-primary underline-offset-4 hover:underline',\n      },\n      effect: {\n        expandIcon: 'group gap-0 relative',\n        ringHover: 'transition-all duration-300 hover:ring-2 hover:ring-primary/90 hover:ring-offset-2',\n        shine:\n          'before:animate-shine relative overflow-hidden before:absolute before:inset-0 before:rounded-[inherit] before:bg-[linear-gradient(45deg,transparent_25%,rgba(255,255,255,0.5)_50%,transparent_75%,transparent_100%)] before:bg-[length:250%_250%,100%_100%] before:bg-no-repeat background-position_0s_ease',\n        shineHover:\n          'relative overflow-hidden before:absolute before:inset-0 before:rounded-[inherit] before:bg-[linear-gradient(45deg,transparent_25%,rgba(255,255,255,0.5)_50%,transparent_75%,transparent_100%)] before:bg-[length:250%_250%,100%_100%] before:bg-[position:200%_0,0_0] before:bg-no-repeat before:transition-[background-position_0s_ease] hover:before:bg-[position:-100%_0,0_0] before:duration-1000',\n        gooeyRight:\n          'relative z-0 overflow-hidden transition-all duration-500 before:absolute before:inset-0 before:-z-10 before:translate-x-[150%] before:translate-y-[150%] before:scale-[2.5] before:rounded-[100%] before:bg-gradient-to-r from-white/40 before:transition-transform before:duration-1000  hover:before:translate-x-[0%] hover:before:translate-y-[0%]',\n        gooeyLeft:\n          'relative z-0 overflow-hidden transition-all duration-500 after:absolute after:inset-0 after:-z-10 after:translate-x-[-150%] after:translate-y-[150%] after:scale-[2.5] after:rounded-[100%] after:bg-gradient-to-l from-white/40 after:transition-transform after:duration-1000  hover:after:translate-x-[0%] hover:after:translate-y-[0%]',\n        underline:\n          'relative !no-underline after:absolute after:bg-primary after:bottom-2 after:h-[1px] after:w-2/3 after:origin-bottom-left after:scale-x-100 hover:after:origin-bottom-right hover:after:scale-x-0 after:transition-transform after:ease-in-out after:duration-300',\n        hoverUnderline:\n          'relative !no-underline after:absolute after:bg-primary after:bottom-2 after:h-[1px] after:w-2/3 after:origin-bottom-right after:scale-x-0 hover:after:origin-bottom-left hover:after:scale-x-100 after:transition-transform after:ease-in-out after:duration-300',\n        gradientSlideShow:\n          'bg-[size:400%] bg-[linear-gradient(-45deg,var(--gradient-lime),var(--gradient-ocean),var(--gradient-wine),var(--gradient-rust))] animate-gradient-flow',\n      },\n      size: {\n        default: 'h-10 px-4 py-2',\n        sm: 'h-9 rounded-md px-3',\n        lg: 'h-11 rounded-md px-8',\n        icon: 'h-10 w-10',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n    },\n  }\n);\n\ninterface IconProps {\n  icon: React.ElementType;\n  iconPlacement: 'left' | 'right';\n}\n\ninterface IconRefProps {\n  icon?: never;\n  iconPlacement?: undefined;\n}\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes\u003cHTMLButtonElement\u003e, VariantProps\u003ctypeof buttonVariants\u003e {\n  asChild?: boolean;\n}\n\nexport type ButtonIconProps = IconProps | IconRefProps;\n\nconst Button = React.forwardRef\u003cHTMLButtonElement, ButtonProps \u0026 ButtonIconProps\u003e(\n  ({ className, variant, effect, size, icon: Icon, iconPlacement, asChild = false, ...props }, ref) =\u003e {\n    const Comp = asChild ? Slot : 'button';\n    return (\n      \u003cComp className={cn(buttonVariants({ variant, effect, size, className }))} ref={ref} {...props}\u003e\n        {Icon \u0026\u0026\n          iconPlacement === 'left' \u0026\u0026\n          (effect === 'expandIcon' ? (\n            \u003cdiv className=\"w-0 translate-x-[0%] pr-0 opacity-0 transition-all duration-200 group-hover:w-5 group-hover:translate-x-100 group-hover:pr-2 group-hover:opacity-100\"\u003e\n              \u003cIcon /\u003e\n            \u003c/div\u003e\n          ) : (\n            \u003cIcon /\u003e\n          ))}\n        \u003cSlottable\u003e{props.children}\u003c/Slottable\u003e\n        {Icon \u0026\u0026\n          iconPlacement === 'right' \u0026\u0026\n          (effect === 'expandIcon' ? (\n            \u003cdiv className=\"w-0 translate-x-[100%] pl-0 opacity-0 transition-all duration-200 group-hover:w-5 group-hover:translate-x-0 group-hover:pl-2 group-hover:opacity-100\"\u003e\n              \u003cIcon /\u003e\n            \u003c/div\u003e\n          ) : (\n            \u003cIcon /\u003e\n          ))}\n      \u003c/Comp\u003e\n    );\n  }\n);\nButton.displayName = 'Button';\n\nexport { Button, buttonVariants };\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003etailwind.config.ts\u003c/summary\u003e\n\n```diff\nconst config = {\n  extend: {\n      keyframes: {\n+       shine: {\n+          '0%': { backgroundPosition: '200% 0' },\n+          '25%': { backgroundPosition: '-200% 0' },\n+          '100%': { backgroundPosition: '-200% 0' },\n+        },\n+       gradientFlow: {\n+          '0%': { 'background-position':'0% 50%' },\n+          '50%': { 'background-position': '100% 50%' },\n+          '100%': { 'background-position': '0% 50%' },\n+        },\n      },\n      animation: {\n+         shine: 'shine 3s ease-out infinite',\n+         'gradient-flow': 'gradientFlow 10s ease 0s infinite normal none running',\n      },\n  },\n}\n```\n\n\u003c/details\u003e\n\n# Usage\n\nExample usage:\n\n```tsx\nimport { Button } from './ui/button';\n\n\u003cButton effect=\"expandIcon\" icon={ArrowRightIcon} iconPlacement=\"right\"\u003e\n  Icon right\n\u003c/Button\u003e;\n```\n\n```tsx\nimport { Button } from './ui/button';\n\n\u003cButton effect=\"gooeyRight\"\u003eGooey right\u003c/Button\u003e;\n```\n\nMix with other variants:\n\n```tsx\nimport { Button } from './ui/button';\n\n\u003cButton variant=\"outline\" effect=\"shineHover\"\u003e\n  Outline with shine hover\n\u003c/Button\u003e;\n```\n\nCheck out the [demo](https://enhanced-button.vercel.app/) to see **all** the different styles.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakobhoeg%2Fenhanced-button","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjakobhoeg%2Fenhanced-button","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakobhoeg%2Fenhanced-button/lists"}