Skip to content

Latest commit

 

History

28 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Argent

Liquid-metal UI for React. Flowing chrome, gold, and gunmetal surfaces that ripple like mercury — real liquid metal, powered by Paper's LiquidMetal WebGL shader, wrapped in components. A metal sibling to Glacé.

argentui.com · npm

Argent

npm i argentui @paper-design/shaders-react

@paper-design/shaders-react is a peer dependency — install it alongside argentui. It's the WebGL shader engine, by Paper, licensed under PolyForm Shield.

import { MetalButton, MetalCard, Metal } from "argentui";
import "argentui/styles.css";

<MetalButton tone="silver">Get started</MetalButton>
<MetalCard tone="gunmetal" sheen>Forged in the browser</MetalCard>

How it works

Each surface renders Paper's LiquidMetal shader with shape="none" so the metal fills the whole element instead of painting a blob. The shader canvas sits behind your content, clipped to the surface's radius. A tone is just a tuned set of shader params (colorBack, colorTint, repetition, distortion, shiftRed/Blue, …). Until the canvas mounts on the client, a static CSS gradient stands in (SSR-safe).

Each surface is its own WebGL canvas, and browsers cap concurrent WebGL contexts (~16). Argent handles this for you: the shader only mounts while a surface is on/near screen (IntersectionObserver) and releases its context when it scrolls away, so a long page stays well under the cap. The static gradient shows in the meantime.

By default the metal is just the edge (variant="border") with a calm interior, which keeps content readable; pass variant="fill" for a full molten surface, or revealOnHover to fill in on interaction.

Components

<MetalButton>

A stamped-metal button: readable at rest with a liquid-metal rim, molten on hover, with a real press (and haptics on supporting devices).

Buttons

<MetalButton tone="gold" size="lg">Buy</MetalButton>
prop type default
tone MetalTone (8 finishes — see Tones) "silver"
size "sm" | "md" | "lg" "md"
speed number 1

<MetalCard>

A padded liquid-metal panel.

<MetalCard tone="gunmetal" sheen>
  <h3>Title</h3>
  <p>Any content — the metal flows behind it.</p>
</MetalCard>

<MetalText>

Metal type. By default the liquid-metal shader is poured into the glyphs — flowing bands, liquid edges, chromatic fringe. Set variant="outline" to run the metal around the edges of each glyph over a dark or gradient interior — the border treatment, for type. The CSS chrome gradient stands in until the shader loads (and wherever WebGL is unavailable); pass shader={false} to use it on its own, free at any scale.

Chrome text

<MetalText tone="silver" fontSize={64}>Quicksilver</MetalText>

// metal edges, dark gradient interior
<MetalText variant="outline" fillGradient={["#23262c", "#0a0b0d"]} fontSize={64}>
  Quicksilver
</MetalText>

<MetalText shader={false} tone="gold" style={{ fontSize: 64 }}>Solid gold</MetalText>  // pure CSS

Shader mode renders the glyphs into an SVG silhouette, which sees system fonts only by default. To use a webfont (e.g. Google Fonts), pass fontCss with an @font-face whose src is a data: URI — it gets embedded in the silhouette and renders correctly (the argentui.com text lab does exactly this). The CSS gradient stands in until the shader loads, and wherever WebGL is unavailable.

<MetalLogo>

Pour the metal into any mark — pass an image with a transparent background and it flows inside the silhouette.

Liquid logo

<MetalLogo src="/logo.svg" tone="silver" size={170} />

<MetalIcon>

Pour the liquid-metal shader into any SVG icon — a lucide-react or Heroicons element, raw SVG, or a URL. React icons are serialized from the DOM to a silhouette; each icon is one WebGL canvas, gated to the viewport like every metal surface.

import { MetalIcon } from "argentui";
import { Sparkles } from "lucide-react";
import { BeakerIcon } from "@heroicons/react/24/solid";

<MetalIcon icon={<Sparkles />} tone="silver" size={32} />
<MetalIcon icon={<BeakerIcon />} tone="gold" size={64} />
<MetalIcon svg="<svg>…</svg>" />          {/* or raw SVG */}
<MetalIcon src="/icon.svg" tone="gunmetal" />  {/* or a URL */}

Buttons take an icon prop too — it renders before the label in the label colour:

<MetalButton tone="silver" icon={<Sparkles />}>Get started</MetalButton>
prop type default
icon / svg / src ReactNode / string / string
tone MetalTone "silver"
size number 32

<MetalToggle> / <MetalProgress> / <MetalBadge>

A mercury switch (the thumb squishes as you press it), a molten progress bar, and metal-rimmed badges.

Controls

<MetalToggle tone="silver" defaultChecked onCheckedChange={setOn} />
<MetalProgress tone="silver" value={64} />
<MetalProgress tone="gold" />  {/* indeterminate */}
<MetalBadge tone="gold">Pro</MetalBadge>

<Metal>

The base primitive every component is built on. Render any element via as.

<Metal as="nav" tone="silver" radius={16} speed={0.5} sheen></Metal>
prop type default notes
as ElementType "div" element/component to render
tone MetalTone "silver" finish (8 tones — see below)
variant "border" | "fill" "border" metal edge only, or full surface
frame "single" | "double" "single" double adds an inner hairline frame
tint boolean false let the metal show faintly through the interior
revealOnHover boolean false fill with metal on hover (border variant)
borderWidth number 1.5 rim thickness (border variant)
radius number 14 corner radius (px)
speed number 1 shader speed (0 pauses)
finish "surface" | "button" | "bar" | "orb" | "rim" per component shape-tuned shader preset (see below)
effect "flow" | "molten" | "ripple" | "chrome" | "wave" "flow" the liquid's motion character — from mirror-still chrome to a heavy molten churn
halo boolean | number false frosted standoff ring outside the metal — a few px of backdrop blur finished with a ~5% hairline (true = 8px; theme the line with --argent-halo-line)
angle number per tone/finish band direction in degrees
metalScale number per finish pattern scale — higher spreads the bands
sheen boolean false specular streak on hover

Theme the border interior with the --argent-panel CSS variable.

Tones

Eight metal finishes: silver, gold, gunmetal, obsidian, and the coloured metals cobalt (blue), crimson (red), amethyst (purple), and emerald (green). Every component takes tone.

<MetalButton tone="cobalt">Blue steel</MetalButton>
<MetalCard tone="amethyst" />
<MetalText tone="emerald">Emerald</MetalText>

Tune any tone's shader params via TONE_PARAMS.

Finishes

One shader tuning can't serve every shape — broad bands that look right on a card read as a smear on a 10px progress bar and a sticker on a 22px toggle thumb. Each component defaults to a finish preset tuned for its geometry, and you can override it anywhere:

finish tuned for character
surface cards, nav, panels broad flowing reflection bands
button buttons spread + calmer warp, label stays readable
bar thin strips (progress) near-vertical stripes crossing the bar
orb small round things (toggle thumbs) one soft highlight, like a polished sphere — with per-instance angle variation so rows don't look cloned
rim hairline edges (badges) dense bands so any visible slice catches light
<Metal tone="silver" finish="rim" angle={120}></Metal>

Tune any tone with TONE_PARAMS, or drop down to <MetalFill> / Paper's <LiquidMetal> directly for full control.

The native engine

Argent also ships its own clean-room WebGL2 shader — pass engine="native" to any surface to use it instead of Paper's. Same recipe (reflection banding, noise flow, chromatic dispersion), zero extra dependencies, MIT all the way down. It currently powers the rim/border look best; the Paper engine remains the default.

<Metal tone="silver" engine="native"></Metal>

Accessibility

The shader pauses under prefers-reduced-motion; toggles are real role="switch" buttons; progress bars carry role="progressbar" with values; labels keep WCAG-ish contrast on every variant. Haptics (navigator.vibrate) fire on press where supported — disable globally with setHaptics(false).

Credits

Liquid-metal shader by Paper (@paper-design/shaders). Argent is the component layer, motion, and theming on top.

License

MIT © Sean Geng. The bundled shader engine (@paper-design/shaders-react, a peer dependency) is licensed separately under PolyForm Shield by Paper.

About

Liquid-metal UI for React — flowing chrome that ripples like mercury, pure CSS + SVG (no WebGL). A metal sibling to Glacé.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages