# Fill Sweep Button

> Button whose fill sweeps in from any of four directions on hover while the text inverts.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/fill-sweep-button
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/fill-sweep-button.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/fill-sweep-button-demo.tsx"
import { FillSweepButton } from "@/components/fill-sweep-button"

export default function FillSweepButtonDemo() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-4 rounded-2xl bg-neutral-100 p-12 dark:bg-neutral-900">
      <FillSweepButton>From left</FillSweepButton>
      <FillSweepButton direction="right">From right</FillSweepButton>
      <FillSweepButton direction="up">From top</FillSweepButton>
      <FillSweepButton direction="down">From bottom</FillSweepButton>
    </div>
  )
}
```

## Source

```tsx title="components/fill-sweep-button.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

export interface FillSweepButtonProps extends React.ComponentProps<"button"> {
  direction?: "left" | "right" | "up" | "down"
}

const origins = {
  left: "origin-left scale-x-0 group-hover:scale-x-100",
  right: "origin-right scale-x-0 group-hover:scale-x-100",
  up: "origin-top scale-y-0 group-hover:scale-y-100",
  down: "origin-bottom scale-y-0 group-hover:scale-y-100",
} as const

export function FillSweepButton({ direction = "left", className, children, ...props }: FillSweepButtonProps) {
  return (
    <button
      type="button"
      className={cn(
        "group relative inline-flex h-12 items-center justify-center overflow-hidden rounded-lg border-2 border-foreground px-8 text-sm font-semibold text-foreground select-none",
        "transition-colors duration-500 hover:text-background",
        "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:outline-none",
        "disabled:pointer-events-none disabled:opacity-50",
        className
      )}
      {...props}
    >
      <span
        aria-hidden
        className={cn("absolute inset-0 bg-foreground transition-transform duration-500 ease-out", origins[direction])}
      />
      <span className="relative">{children}</span>
    </button>
  )
}
```
