Skip to content
goodtabs UI
BrowseBrowse components

Shine button

The primary pill with a 1px top shine and a soft shadow, for hero and page actions.

npx shadcn@latest add https://ui.goodtabs.co/r/shine-button.json

With the @goodtabs namespace in components.json: npx shadcn@latest add @goodtabs/shine-button

The lg size next to an outline button, as in a hero.

Default size

32px tall for forms and toolbars, next to a ghost cancel.

With a trailing arrow

asChild makes it a link; the arrow sits inline-end.

Usage

import { ShineButton } from "@/components/ui/shine-button"

<ShineButton size="lg">Get started</ShineButton>
<ShineButton asChild><a href="/docs">Read the docs</a></ShineButton>

Props

PropTypeDefaultDescription
size"default" | "lg""default"32px, or 44px with 16px text for hero actions.
asChildbooleanfalseRender the child element, for example an anchor, with the styles.

Source

shine-button/shine-button.tsx
import * as React from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

type ShineButtonProps = Omit<React.ComponentProps<typeof Button>, "variant" | "size"> & {
  /** 32px for app chrome, 44px with 16px text for hero actions. */
  size?: "default" | "lg";
};

/**
 * The primary pill with a 1px top shine and the soft shadow stack.
 * Hover darkens to 90% opacity; nothing lifts or scales.
 */
export function ShineButton({ size = "default", className, ...props }: ShineButtonProps) {
  return (
    <Button
      variant="default"
      size={size}
      className={cn(
        "inset-shadow-[0_1px_0_0_var(--highlight,transparent)] transition-[background-color,opacity] duration-100 ease-out",
        className,
      )}
      {...props}
    />
  );
}

For AI agents

Hand your agent this page, the markdown at /components/shine-button/prompt.md, or the Copy AI prompt button above.

When to use

  • The one primary action in a hero, a pricing card or a form
  • Next to an outline or ghost button that carries the secondary action
  • Where the plain Button looks flat on a dark surface and needs a hint of lift

When not to use

  • For more than one action in a group; one shine button per view
  • In dense toolbars and tables, where the plain Button is enough
  • For destructive actions, which use the destructive token

Agent notes

  • It is shadcn's default Button plus an inset top highlight, so every Button prop applies except variant
  • The shine reads the --highlight CSS variable and falls back to nothing; define --highlight in your theme to see it
  • Hover is the Button's bg-primary/90; there is no transform, so it sits still next to other buttons
  • lg is 44px with 16px text, meant for heroes only; default is the 32px control height