Actions
Button
A button.
Import
import { Button } from '@the_viveksingh/vivek-ui'Variants
Four variants, mapped to a data attribute rather than a class-name string.
<Button>Solid</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>Sizes and full width
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button fullWidth>Full width</Button>Loading
loading also disables the button, so a submit cannot fire twice while a request is in flight.
<Button loading>Saving changes</Button>
<Button loading variant="outline">Loading</Button>
<Button disabled>Disabled</Button>As a link
asChild renders your element instead of a <button>. A link that looks like a button must be an anchor — otherwise middle-click, cmd-click and "open in new tab" all break, and a screen reader announces the wrong role.
import Link from 'next/link'
<Button asChild>
<Link href="/docs/installation">Get started</Link>
</Button>Overriding styles
Every library selector is wrapped in :where(), which has specificity zero — so one flat class of your own wins, with no !important.
/* your stylesheet */
.my-cta { background: #db2777; border-radius: 999px; }
<Button className="my-cta">Beats the library</Button>Props
Generated from the package's own type declarations, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'solid' | 'outline' | 'ghost' | 'link' | — | — |
size | 'sm' | 'md' | 'lg' | — | — |
fullWidth | boolean | — | — |
loading | boolean | — | — |
asChild | boolean | — | Render the caller's element instead of a `<button>`, keeping every style and data attribute. This is how a button navigates without the library depending on a router: ```tsx <Button asChild><Link href="/pricing">Pricing</Link></Button> ``` A link that looks like a button must be an `<a>`, not a `<button>` with an onClick — otherwise middle-click, cmd-click, "open in new tab" and "copy link address" all break, and a screen reader announces the wrong role. `loading` and `disabled` are ignored when `asChild` is set: `disabled` is not a valid attribute on an anchor, and a spinner inside someone else's element would fight their children. Use a real `<button>` for anything with a pending state. |
Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.
Rendering
Button carries no 'use client' directive and renders directly in a React Server Component. No client JavaScript is shipped for it.