Focus Halo
A keyboard-visible glow for primary controls.
"use client";
import "./styles/focus-halo.css";
export default function FocusHalo({ variant = "Soft" }: { variant?: string }) {
return <button className={`ward-focus-halo ${variant === "Bright" ? "is-bright" : ""}`} type="button">Focus this control</button>;
}.ward-focus-halo { height: 36px; padding: 0 16px; border: 0; border-radius: 999px; background: var(--primary); color: var(--primary-foreground); font: inherit; font-weight: 500; cursor: pointer; transition: box-shadow 180ms cubic-bezier(.2, 0, 0, 1), transform 180ms cubic-bezier(.2, 0, 0, 1); }
.ward-focus-halo:hover, .ward-focus-halo:focus-visible { box-shadow: 0 0 0 3px var(--background), 0 0 0 5px var(--ring); transform: translateY(-1px); outline: 0; }
.ward-focus-halo.is-bright:hover, .ward-focus-halo.is-bright:focus-visible { box-shadow: 0 0 0 3px var(--background), 0 0 0 5px var(--foreground), 0 0 24px color-mix(in oklab, var(--foreground) 35%, transparent); }
@media (prefers-reduced-motion: reduce) { .ward-focus-halo { transition: none; } .ward-focus-halo:hover, .ward-focus-halo:focus-visible { transform: none; } }Installation
pnpm dlx shadcn@latest add @ward/focus-halonpx shadcn@latest add @ward/focus-haloyarn dlx shadcn@latest add @ward/focus-halobunx --bun shadcn@latest add @ward/focus-haloAdd the Ward registry to components.json once:
"registries": {
"@ward": "https://ward.so/r/{name}.json"
}Or install from the URL with no configuration: npx shadcn@latest add https://ward.so/r/focus-halo.json
Copy each file from the Code tab into:
components/ward/FocusHalo.tsxcomponents/ward/styles/focus-halo.css
Update the import paths to match your project.
Usage
import FocusHalo from "@/components/ward/FocusHalo";<FocusHalo variant="Bright" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "Soft" | "Bright" | "Soft" | Strength of the focus ring drawn around the button. |
Ward · Version 1.1.0 · Registry manifest