FancyButton
A solid button with a fancy gradient finish and fully accessible focus handling
Completeness: styles-sufficient
The stylesheet is the whole component. There is no keyboard map beyond what the native element already does and nothing sets state at runtime that the CSS keys on, so a CSS-only port reproduces it.
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-labelwhen usingisIconOnly.
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.
A worked example is in Styling.
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:
:hoveror[data-hovered="true"](brightens the sheen layer) - Active/Pressed:
:activeor[data-pressed="true"](includes scale transform) - Focus:
:focus-visibleor[data-focus-visible="true"](shows focus ring) - Disabled:
:disabledor[aria-disabled="true"](reduced opacity, no pointer events, fancy layers removed) - Pending:
[data-pending](no pointer events during loading)
API Reference
FancyButton Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'neutral' | 'danger' | 'basic' | 'primary' | Visual style variant |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the button |
fullWidth | boolean | false | Whether the button should take full width of its container |
isDisabled | boolean | false | Whether the button is disabled |
isIconOnly | boolean | false | Whether the button contains only an icon (requires aria-label) |
onPress | (e: PressEvent) => void | - | Handler called when the button is pressed |
children | React.ReactNode | (values: ButtonRenderProps) => React.ReactNode | - | Button content or render prop |