JSPM

gradient-border-react

0.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 17
  • Score
    100M100P100Q77330F
  • License MIT

Animated gradient border that flows around any element. A tiny, dependency-free React component for React 18 and 19.

Package Exports

  • gradient-border-react

Readme

gradient-border-react

tests coverage license npm version npm downloads bundle size

๐ŸŒ Live demo โ†’

An animated gradient border that flows around any element. Tiny, dependency-free, and it respects prefers-reduced-motion out of the box. Works with React 18 and React 19.

<GradientBorder colors={['#7C3AED', '#06B6D4', '#10B981']} radius={16} glow>
  <div style={{ padding: 24 }}>Wrap me โœจ</div>
</GradientBorder>

No CSS file to import, no canvas, no requestAnimationFrame โ€” just a masked, rotating conic-gradient driven by a registered @property. One <style> of keyframes is injected once, and that's the whole runtime.

Install

From GitHub (always works):

pnpm add github:kea0811/gradient-border-react

From npm (when published to npm):

pnpm add gradient-border-react

Prefer npm or yarn? npm install gradient-border-react / yarn add gradient-border-react work too.

react and react-dom are peer dependencies (^18 || ^19).

Quick start

import { GradientBorder, presets } from 'gradient-border-react';

export function ProfileCard() {
  return (
    <GradientBorder colors={presets.aurora} radius={16} borderWidth={2} background="#0d0d16">
      <div style={{ padding: 24 }}>
        <h3>Ada Lovelace</h3>
        <p>The first programmer.</p>
      </div>
    </GradientBorder>
  );
}

That's it โ€” the border animates immediately. Wrap a card, a button, an avatar, an input; the gradient keeps flowing around whatever's inside.

Features

  • ๐ŸŽˆ Tiny & dependency-free โ€” a couple of inline styles and one injected keyframe block.
  • ๐ŸŒˆ Eight presets plus any custom color array you like.
  • โ™ฟ๏ธ Reduced-motion aware โ€” the ring freezes to a static gradient when the user asks for less motion, and the decorative layers are hidden from assistive tech.
  • ๐Ÿงฉ Composable โ€” use the <GradientBorder> component, or the useGradientBorder() hook to paint the look onto your own markup.
  • โš›๏ธ React 18 & 19 โ€” StrictMode-safe; all lifecycle lives in a single effect.
  • ๐Ÿงช 100% test coverage, TypeScript strict mode, ESM + CJS + types.

API

<GradientBorder>

A <div> wrapper around your content. Accepts every standard div prop (className, style, onClick, aria-*, a forwarded ref, โ€ฆ) plus:

Prop Type Default Description
colors string[] presets.aurora Colors the gradient cycles through. Treated as a loop; a single color is allowed.
borderWidth number 2 Border thickness, in pixels.
radius number 12 Corner radius, in pixels.
duration number 4 Seconds for one full rotation. Lower is faster.
direction 'cw' | 'ccw' 'cw' Spin direction.
paused boolean false Freeze the animation on its current frame.
background string 'transparent' Fill painted inside the border (turn the frame into a card).
glow boolean false Add a soft, blurred glow of the same gradient behind the box.

useGradientBorder(options?)

The component is a thin wrapper around this hook. It returns the inline styles for each layer, so you can compose the border onto any element you control:

import { useGradientBorder, presets } from 'gradient-border-react';

function FancyButton() {
  const { ring, content } = useGradientBorder({ colors: presets.candy, radius: 999 });
  return (
    <div style={ring}>
      <button style={content}>Click me</button>
    </div>
  );
}

It returns { outer, glow, ring, content } โ€” all React.CSSProperties. options takes the same fields as the component props above.

presets / presetNames

import { presets, presetNames } from 'gradient-border-react';

presets.sunset; // ['#F59E0B', '#EF4444', '#EC4899', '#8B5CF6']
presetNames;    // ['aurora', 'sunset', 'ocean', 'candy', 'ember', 'mint', 'mono', 'rainbow']

usePrefersReducedMotion()

The same accessibility hook the border uses internally, exported for convenience. Returns a boolean that updates live when the user's setting changes.

Accessibility

GradientBorder reads prefers-reduced-motion and renders a static gradient when reduced motion is requested โ€” no flag needed. The glow and ring layers are purely decorative and marked aria-hidden, so screen readers only ever see your content.

Browser support

The effect relies on CSS @property to smoothly interpolate the gradient angle (Chrome/Edge 85+, Safari 16.4+, Firefox 128+). In older engines the gradient still renders โ€” it just won't rotate, which is a perfectly fine fallback.

Live demo

See every prop in action: gradient-border-react.vercel.app

To run it locally:

pnpm install
pnpm build        # build the library once
pnpm demo:dev     # start the demo at http://localhost:5173

Contributing

Issues and PRs are welcome. To hack on it:

pnpm install
pnpm test          # run the suite
pnpm test:coverage # 100% across the board
pnpm build         # ESM + CJS + .d.ts

License

MIT ยฉ kea0811