Componentnavigation0.79 KB gzipZero dependencies

Scroll Top

Floating elevator button that scrolls smoothly to page top.

Preview

Live Preview
▲ELEVATOR · TOP
Appears automatically on long pages with smooth scroll to top

Installation

Tokens guide →

Add to your project via CLI (zero dependencies, code you own):

npx bigbullui add scroll-top

Or install the full npm package:

npm install bigbullui
import { ScrollTop } from "@/components/ui/scroll-top";

<ScrollTop threshold={150} label="TOP" />

Usage guidance

Use Scroll Top when a ticket stub surface needs Floating elevator button that scrolls smoothly to page top. Keep props minimal and prefer composition with sibling stubs.

Avoid Scroll Top for long form flows or dense data grids where a dedicated layout block fits better.

Source code

scroll-top.tsx

Zero dependencies (only React + utils). Copy and paste directly into your project:

"use client";

import * as React from "react";
import { cn } from "./lib/utils";

export interface ScrollTopProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  threshold?: number;
  label?: string;
  className?: string;
}

export function ScrollTop({
  threshold = 200,
  label = "TOP",
  className,
  ...props
}: ScrollTopProps) {
  const [visible, setVisible] = React.useState(false);

  React.useEffect(() => {
    const checkScroll = () => {
      setVisible(window.scrollY > threshold);
    };

    window.addEventListener("scroll", checkScroll, { passive: true });
    checkScroll();
    return () => window.removeEventListener("scroll", checkScroll);
  }, [threshold]);

  const scrollToTop = () => {
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  if (!visible) return null;

  return (
    <button
      type="button"
      onClick={scrollToTop}
      aria-label="Scroll to top of page"
      className={cn(
        "fixed bottom-6 right-6 z-40 flex items-center gap-1.5 rounded-lg border-2 border-foreground bg-card px-3 py-2 font-mono text-xs font-bold text-foreground shadow-lg transition-all hover:bg-accent hover:text-accent-foreground hover:scale-105 active:scale-95 animate-[scale-in_0.15s_ease-out_both] cursor-pointer outline-1 outline-dashed outline-offset-[-4px]",
        className
      )}
      {...props}
    >
      <span className="inline-block transition-transform duration-200 group-hover:-translate-y-0.5 animate-bounce">
        ▲
      </span>
      <span className="text-[10px] tracking-widest">{label}</span>
    </button>
  );
}

Props

PropTypeDescription
threshold?number
label?string
className?string