Radio

A restyled native <input type="radio">. Group them by giving several the same name. All native attributes pass through.

Colors (solid)

Sizes

Real use · pick a plan

Using Radio

Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.

Plain HTML — CSS classes

The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path is complete for Radio — it needs no JavaScript, so the classes below are the whole story.

/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";

Root class radio, with 13 modifiers:

  • .radio
  • .radio-accent
  • .radio-error
  • .radio-info
  • .radio-lg
  • .radio-md
  • .radio-neutral
  • .radio-primary
  • .radio-secondary
  • .radio-sm
  • .radio-success
  • .radio-warning
  • .radio-xl
  • .radio-xs

React

Typed components over those same classes, with behavior and accessibility from Base UI.

npm i @wizeworks/silicaui-react
import { Radio } from "@wizeworks/silicaui-react";

Props

PropTypeRequiredDescription
colorSilicaColornoAccent color; maps to radio-<color> (checked dot + focus ring).
sizeSilicaSizenoDefault md.
childrenReact.ReactNodenoCaption. Wraps the control in a <label> so the text is a click target.

Source of the demo above

The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.

Show source
import { useState } from "react";
import { Radio } from "@wizeworks/silicaui-react";
import { Section } from "../lib/Section";
import { ColorVariantSizeGrid } from "../lib/ColorGrid";

const PLANS = [
    { id: "starter", label: "Starter — $9/mo" },
    { id: "pro", label: "Pro — $29/mo" },
    { id: "enterprise", label: "Enterprise — custom" },
];

export function RadioDemo() {
    const [plan, setPlan] = useState("pro");

    return (
        <>
            <ColorVariantSizeGrid
                Component={Radio}
                render={({ color, size }) => (
                    <label className="flex items-center gap-2 text-sm">
                        <Radio name={`radio-${color ?? size}`} color={color} size={size} defaultChecked />
                        {color ?? size}
                    </label>
                )}
            />

            <Section title="Real use · pick a plan">
                <div className="flex flex-col gap-2">
                    {PLANS.map((p) => (
                        <label key={p.id} className="flex items-center gap-2 text-sm">
                            <Radio
                                name="plan"
                                color="primary"
                                checked={plan === p.id}
                                onChange={() => setPlan(p.id)}
                            />
                            {p.label}
                        </label>
                    ))}
                </div>
            </Section>
        </>
    );
}

Vanilla — node tree to HTML

The framework-neutral form of Radio. Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.

npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviors
import { atom, toHtml } from "@wizeworks/silicaui-html";

const node = atom("Radio", "radio", { /* props */ }, [/* children */]);
const markup = toHtml(node);

Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "radio radio-primary" rather than passing a colour as a prop.

Takes children
yes
Hydrated by
nothing — this one is static markup

The full API for Radio, on every path, is available through the Silica MCP server.