Buttons, icon buttons, links and key caps: the things you press.
Every button is a small piece of lit metal in five finishes and five sizes. Labels say what happens; icon-only buttons always carry a name.
6 parts
The lit-metal button in five finishes and five sizes, with icons, a loading state and shortcut hints.
import { Button } from '@rchursin/product/ui'
/** * Five finishes. Primary is graphite in light mode and silver in dark mode. Inverse is always the * opposite of the page, so it goes on an inverted panel. */export default function ButtonVariants() { return ( <div className="flex flex-wrap items-center justify-center gap-3"> <Button>Save changes</Button> <Button variant="secondary">Preview</Button> <Button variant="outline">Export</Button> <Button variant="ghost">Cancel</Button> <div className="flex items-center gap-3 rounded-xl bg-inverse py-2 pr-2 pl-3.5 text-[12px] text-on-inverse/70"> Inverted panel <Button variant="inverse">Publish</Button> </div> </div> )}A square button with just an icon. The label is required: it is the accessible name and the tooltip.
import { IconButton } from '@rchursin/product/ui'
/** The label is required: it is the accessible name and the tooltip. Name the action, not the picture. */export default function IconButtonBasic() { return ( <div className="flex items-center justify-center gap-2"> <IconButton icon="pencil" label="Edit task" /> <IconButton icon="copy" label="Duplicate task" /> <IconButton icon="archive" label="Archive task" /> <IconButton icon="trash" label="Delete task" /> </div> )}Keyboard keys cut from the same metal as the buttons, and shortcuts written as key caps.
import { Kbd, KeyCombo } from '@rchursin/product/ui'
/** Key caps cut from the same metal as the buttons. "mod" becomes ⌘ or Ctrl for the visitor. */export default function KeyCombos() { return ( <dl className="grid grid-cols-[auto_1fr] items-center gap-x-6 gap-y-3 text-[13px]"> <dt> <KeyCombo combo="mod+k" /> </dt> <dd className="text-fg-2">Open search</dd> <dt> <KeyCombo combo="g" then="i" /> </dt> <dd className="text-fg-2">Go to inbox</dd> <dt> <KeyCombo combo="shift+enter" /> </dt> <dd className="text-fg-2">New line</dd> <dt> <Kbd>Esc</Kbd> </dt> <dd className="text-fg-2">Close</dd> </dl> )}A link cut from the same lit metal as Button, for calls to action that go somewhere.
import { ButtonLink } from '@rchursin/home/ui'
/** * A link cut from the same metal as Button. It goes somewhere, so it is an <a>: these four jump * to sections further down this page. */export default function ButtonLinkVariants() { return ( <div className="flex flex-wrap items-center justify-center gap-3"> <ButtonLink href="#usage">Get started</ButtonLink> <ButtonLink href="#examples" variant="secondary"> See examples </ButtonLink> <ButtonLink href="#api" variant="outline"> Read the API </ButtonLink> <ButtonLink href="#guidelines" variant="ghost"> Guidelines </ButtonLink> </div> )}Copy text to the clipboard with one press: a pearl button that says “Copied”, a quiet one for code, and the helper under both.
import { CopyButton } from '@rchursin/home/ui'import { SampleBadge } from '@rchursin/product/shell/layout'import { CopyCodeButton } from '@rchursin/product/ui'
/** * Both copy for real. CopyButton (pearl) changes its words to "Copied" for 1.6 seconds. * CopyCodeButton (ghost) keeps its name, shows a check for 2 seconds and announces the result. */const inviteLink = 'https://example.com/invite/k7q2-m9xd'const projectId = 'prj_4fd81c2e'
export default function CopyButtonBasic() { return ( <div className="lux-card w-full max-w-md rounded-2xl bg-raised"> <div className="flex items-center justify-between gap-3 border-b border-line px-4 py-3"> <h3 className="text-[14px] font-semibold tracking-[-0.01em] text-fg">Share project</h3> <SampleBadge /> </div> <ul className="flex flex-col divide-y divide-line"> <li className="flex items-center gap-3 px-4 py-3"> <div className="flex min-w-0 flex-1 flex-col gap-0.5"> <span className="text-[12px] text-fg-3">Invite link</span> <span className="truncate font-mono text-[12.5px] text-fg">{inviteLink}</span> </div> <CopyButton text={inviteLink} label="Copy link" /> </li> <li className="flex items-center gap-3 px-4 py-3"> <div className="flex min-w-0 flex-1 flex-col gap-0.5"> <span className="text-[12px] text-fg-3">Project ID</span> <span className="truncate font-mono text-[12.5px] text-fg">{projectId}</span> </div> <CopyCodeButton text={projectId} what="project ID" /> </li> </ul> </div> )}A shimmer button, a shiny announcement pill and a glowing border, from the launch-page screens.
import { ShimmerButton, ShinyPill } from '@rchursin/screens/magic-ui/parts'
/** * The three effects as they sit on a launch page: an announcement pill, a shimmer button and a * pill with a glowing border. Each light runs once on arrival (and the beam again on hover); * nothing moves with reduced motion. These links jump to sections of this page. */export default function EffectButtonsShowcase() { return ( <div className="flex flex-col items-center gap-7 text-center"> <ShinyPill href="#examples">See each effect on its own</ShinyPill> <div className="flex flex-wrap items-center justify-center gap-4"> <ShimmerButton href="#usage">Get started</ShimmerButton> <a href="#api" className="fx-hover-border flex focus-ring transition-transform active:scale-[0.975]"> <span className="flex h-10 items-center rounded-full bg-surface px-5.5 text-sm font-medium text-fg">Read the API</span> </a> </div> </div> )}