@maruwtc/ani-button
v0.1.2
Published
Animated React button component built with Tailwind CSS.
Downloads
253
Readme
AniButton
Animated React button component built with Tailwind CSS, Radix Slot, CVA, and Lucide.
Install
npm install @maruwtc/ani-buttonAniButton expects React and Tailwind CSS to be available in your app:
npm install react react-dom tailwindcssBasic usage
import { AniButton } from "@maruwtc/ani-button"
export function Example() {
return <AniButton icon="default">Continue</AniButton>
}Tailwind setup
This package ships Tailwind utility classes in the built component. Make sure your app scans the installed package so Tailwind includes those classes.
For Tailwind CSS v4:
@import "tailwindcss";
@source "../node_modules/@maruwtc/ani-button";For Tailwind CSS v3:
export default {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@maruwtc/ani-button/dist/**/*.{js,cjs}",
],
}Theme variables
AniButton uses CSS variables from your app theme. If you use shadcn/ui or Tailwind v4 theme variables, these may already exist.
At minimum, define the variables used by the colors you choose:
:root {
--color-card: white;
--color-card-foreground: #111111;
--color-border: #e5e7eb;
--color-foreground: #111111;
--color-background: white;
--color-primary: #111111;
--color-primary-foreground: white;
--color-secondary: #f4f4f5;
--color-secondary-foreground: #18181b;
--color-destructive: #dc2626;
--color-destructive-foreground: white;
}If your app uses dark mode with a .dark class, define dark values too:
.dark {
--color-card: #18181b;
--color-card-foreground: #fafafa;
--color-border: #3f3f46;
--color-foreground: #fafafa;
--color-background: #09090b;
--color-primary: #fafafa;
--color-primary-foreground: #18181b;
--color-secondary: #27272a;
--color-secondary-foreground: #fafafa;
--color-destructive: #ef4444;
--color-destructive-foreground: white;
}Sizes
Available sizes are sm, default, and lg.
import { AniButton } from "@maruwtc/ani-button"
export function Sizes() {
return (
<div className="flex items-center gap-3">
<AniButton size="sm" icon="default">Small</AniButton>
<AniButton size="default" icon="default">Default</AniButton>
<AniButton size="lg" icon="default">Large</AniButton>
</div>
)
}Colors
Available colors are default, primary, secondary, destructive, and success.
import { AniButton } from "@maruwtc/ani-button"
export function Colors() {
return (
<div className="flex flex-wrap items-center gap-3">
<AniButton color="default" icon="default">Default</AniButton>
<AniButton color="primary" icon="default">Primary</AniButton>
<AniButton color="secondary" icon="default">Secondary</AniButton>
<AniButton color="destructive" icon="default">Delete</AniButton>
<AniButton color="success" icon="default">Success</AniButton>
</div>
)
}Icons
Use icon="default" for the built-in arrow icon.
<AniButton icon="default">Next</AniButton>Pass a React node to use a custom icon:
import { Download } from "lucide-react"
import { AniButton } from "@maruwtc/ani-button"
export function DownloadButton() {
return (
<AniButton icon={<Download className="size-4" />}>
Download
</AniButton>
)
}Omit the label for an icon-only button. Add an accessible label with aria-label.
import { Download } from "lucide-react"
import { AniButton } from "@maruwtc/ani-button"
export function IconOnlyButton() {
return (
<AniButton
aria-label="Download file"
icon={<Download className="size-4" />}
/>
)
}Icon motion
The default motion is rotate. Use iconMotion="none" to disable icon rotation.
<AniButton icon="default" iconMotion="none">
No icon rotation
</AniButton>Active state
Use active to render the filled hover state without requiring hover.
<AniButton active icon="default">
Active
</AniButton>Links with asChild
Use asChild to render the button styles on another component or element, such as a Next.js Link.
import Link from "next/link"
import { AniButton } from "@maruwtc/ani-button"
export function LinkButton() {
return (
<AniButton asChild icon="default">
<Link href="/dashboard">Open dashboard</Link>
</AniButton>
)
}Plain anchor example:
<AniButton asChild icon="default">
<a href="https://example.com">Visit site</a>
</AniButton>Form buttons
AniButton accepts normal button props such as type, disabled, onClick, and aria-*.
import { AniButton } from "@maruwtc/ani-button"
export function SubmitButton({ pending }: { pending: boolean }) {
return (
<AniButton
type="submit"
color="primary"
icon="default"
disabled={pending}
>
{pending ? "Saving" : "Save changes"}
</AniButton>
)
}Styling overrides
Use className for the root element, iconClassName for the icon wrapper, and labelClassName for the label.
<AniButton
icon="default"
className="[--ani-btn-fill:#2563eb]"
labelClassName="font-semibold"
>
Custom fill
</AniButton>You can override the internal sizing CSS variables when you need a custom one-off size:
<AniButton
icon="default"
className="[--ani-btn-height:44px] [--ani-btn-icon:32px] [--ani-btn-font:14px]"
>
Compact
</AniButton>Props
type AniButtonProps = React.ComponentProps<"button"> & {
asChild?: boolean
active?: boolean
icon?: React.ReactNode | "default"
text?: React.ReactNode
iconClassName?: string
labelClassName?: string
size?: "sm" | "default" | "lg"
color?: "default" | "primary" | "secondary" | "destructive" | "success"
iconMotion?: "none" | "rotate"
}Prefer children for the visible label:
<AniButton icon="default">Continue</AniButton>The text prop is also supported:
<AniButton icon="default" text="Continue" />Exports
import {
AniButton,
aniButtonVariants,
type AniButtonProps,
} from "@maruwtc/ani-button"Troubleshooting
If the button appears unstyled, check that Tailwind scans the package path.
If colors are missing, define the required --color-* CSS variables in your app.
If you publish a new package version and npm returns Cannot publish over previously published version, bump the version before publishing:
npm version patch
npm publish --access publicRelease
npm install
npm run build
npm publish --access public