Components
Button
Triggers an action or event. Supports multiple visual variants and sizes, and can render as any element via the asChild prop.
Installation
Add the Button component to your project using the Viana CLI. This copies the source files directly into your repository and installs any required dependencies.
npx viana-kit add buttonThis will create two files in your project:
- –
src/components/ui/button.tsx— the base shadcn/ui primitive (do not modify) - –
src/components/primitives/AppButton.tsx— the Viana Kit wrapper (do not modify)
Import
import { AppButton } from "@/components/primitives/AppButton"Variants
Use the variant prop to change the visual style. The default variant is for primary actions — use it sparingly, one per view.
| Variant | When to use |
|---|---|
| default | Primary action. One per view. |
| secondary | Lower-emphasis action alongside a primary. |
| outline | Secondary action. Bordered, transparent background. |
| ghost | Minimal. No chrome until hovered. Good for toolbars. |
| destructive | Irreversible or dangerous action. Renders in red. |
| link | Inline text link with underline on hover. |
Sizes
Use the size prop to adjust height, padding, and font size. Icon sizes render as a square and should contain only an icon element.
Disabled
Pass the disabled prop to disable interaction. Pointer events are blocked and opacity is reduced to 50%.
Rendering as a link
Pass asChild to merge button styles onto the immediate child element. This is the correct way to render a button as a Next.js Link.
import Link from "next/link"
import { AppButton } from "@/components/primitives/AppButton"
export function NavigateButton() {
return (
<AppButton asChild>
<Link href="/dashboard">Go to dashboard</Link>
</AppButton>
)
}API Reference
AppButton extends all native <button> HTML attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | "default" | Visual style of the button. |
| size | "xs" | "sm" | "default" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "default" | Controls height, padding, and font size. |
| asChild | boolean | false | Merges props onto the child element instead of rendering a <button>. |
| disabled | boolean | false | Disables interaction and reduces opacity to 50%. |
| className | string | — | Additional Tailwind classes merged via cn(). Prefer the wrapper pattern for reusable overrides. |
Source
"use client"
import { Button, buttonVariants } from "@/components/ui/button"
import type { VariantProps } from "class-variance-authority"
type AppButtonProps = React.ComponentProps<typeof Button> &
VariantProps<typeof buttonVariants>
function AppButton(props: AppButtonProps) {
return <Button {...props} />
}
export { AppButton, type AppButtonProps }