FancyButton

A solid button with a fancy gradient finish and fully accessible focus handling

Import

import { FancyButton } from '@blakeui/react';

Usage

"use client";

import {FancyButton} from "@blakeui/react";

export function Basic() {
  return <FancyButton onPress={() => console.log("FancyButton pressed")}>Click me</FancyButton>;
}

Variants

import {FancyButton} from "@blakeui/react";

export function Variants() {
  return (
    <div className="flex flex-wrap gap-3">

The neutral variant uses theme-inverted ink: dark-on-light in light mode and light-on-dark in dark mode. The basic variant is a quiet bordered button that opts out of the fancy gradient layers.

With Icons

import {FancyButton} from "@blakeui/react";
import {Envelope, Globe, Plus, TrashBin} from "@gravity-ui/icons";

export function WithIcons() {
  return (

Icon Only

Icon-only buttons have no visible text, so an aria-label is required for screen reader users.

import {FancyButton} from "@blakeui/react";
import {Ellipsis, Gear, TrashBin} from "@gravity-ui/icons";

export function IconOnly() {
  return (

Sizes

import {FancyButton} from "@blakeui/react";

export function Sizes() {
  return (
    <div className="flex items-center gap-3">

Disabled State

When disabled, the fancy gradient layers are removed so the button reads inert.

import {FancyButton} from "@blakeui/react";

export function Disabled() {
  return (
    <div className="flex flex-wrap gap-3">

Accessibility

FancyButton is built on the same React Aria button primitive as Button:

  • Focus: the shared focus ring appears on keyboard focus only (:focus-visible / [data-focus-visible="true"]) — mouse clicks never show a ring, and the outline is never removed without a replacement.
  • Disabled: uses the shared disabled status (reduced opacity, no pointer events, disabled cursor) and hides the decorative gradient layers.
  • Reduced motion: the sheen transition and the pressed scale transform are disabled under prefers-reduced-motion.
  • Icon only: always pass aria-label when using isIconOnly.

Styling

Passing Tailwind CSS classes

import { FancyButton } from '@blakeui/react';

function CustomFancyButton() {
  return (
    <FancyButton className="rounded-lg">
      Custom Radius
    </FancyButton>
  );
}

Customizing the component classes

To customize the FancyButton component classes, you can use the @layer components directive.
Learn more.

@layer components {
  .fancy-button {
    @apply rounded-lg;
  }
}

blakeUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The FancyButton component uses these CSS classes (View source styles):

Base & Size Classes

  • .fancy-button - Base fancy button styles (gradient inner border + sheen layers)
  • .fancy-button--sm - Small size variant
  • .fancy-button--md - Medium size variant
  • .fancy-button--lg - Large size variant

Variant Classes

  • .fancy-button--primary
  • .fancy-button--neutral
  • .fancy-button--danger
  • .fancy-button--basic

Modifier Classes

  • .fancy-button--icon-only
  • .fancy-button--icon-only.fancy-button--sm
  • .fancy-button--icon-only.fancy-button--lg

Interactive States

The fancy button supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover or [data-hovered="true"] (brightens the sheen layer)
  • Active/Pressed: :active or [data-pressed="true"] (includes scale transform)
  • Focus: :focus-visible or [data-focus-visible="true"] (shows focus ring)
  • Disabled: :disabled or [aria-disabled="true"] (reduced opacity, no pointer events, fancy layers removed)
  • Pending: [data-pending] (no pointer events during loading)

API Reference

FancyButton Props

PropTypeDefaultDescription
variant'primary' | 'neutral' | 'danger' | 'basic''primary'Visual style variant
size'sm' | 'md' | 'lg''md'Size of the button
fullWidthbooleanfalseWhether the button should take full width of its container
isDisabledbooleanfalseWhether the button is disabled
isIconOnlybooleanfalseWhether the button contains only an icon (requires aria-label)
onPress(e: PressEvent) => void-Handler called when the button is pressed
childrenReact.ReactNode | (values: ButtonRenderProps) => React.ReactNode-Button content or render prop

On this page