Primary Button

Free

The default call to action, solid fill with hover and focus states.

npx shadcn@latest add @ui-shrushank/primary-button

The install writes a single file to components/ui/PrimaryButton.tsx, which exports PrimaryButton.

tsx
import { PrimaryButton } from "@/components/ui/PrimaryButton";
tsx
<PrimaryButton>Label</PrimaryButton>

Needs framer-motion installed. The shadcn CLI adds it for you.

The default call-to-action; every library needs the anchor case.

Solid fill, explicit hover and focus-visible states, one accent token.

Focus state is separate from hover so keyboard users get the same affordance mouse users get; a CTA with no visible focus ring is the most common a11y failure in button kits.

Every line below was read out of the file you are about to copy, so you can check each one against the source at the bottom of this page.

  • Has an explicit prefers-reduced-motion branch: the animation is dropped for an instant state change, and the component stays fully usable without it.
  • Draws a focus-visible ring that is separate from its hover treatment, so keyboard users get an affordance mouse users do not take away.

1 required, 0 optional.

childrenrequired
React.ReactNode

One file, no runtime package. Copy it, or install it with the command at the top of this page.

PrimaryButton.tsx
"use client";import { motion, useReducedMotion } from "framer-motion";export function PrimaryButton({ children }: { children: React.ReactNode }) {  const shouldReduceMotion = useReducedMotion();  return (    <motion.button      whileTap={shouldReduceMotion ? undefined : { scale: 0.98 }}      transition={{ duration: 0.12, ease: [0.22, 1, 0.36, 1] }}      className="inline-flex h-10 items-center justify-center rounded-md bg-emerald-700 px-4 text-sm font-medium text-white transition-colors duration-150 hover:bg-emerald-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-emerald-600 active:bg-emerald-900 disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:outline-emerald-400"    >      {children}    </motion.button>  );}