Button
A clickable element for triggering actions or submitting forms.
---import { ArrowUpIcon } from '@lucide/astro';
import Button from '@bejamas/ui/components/Button.astro';---
<div class="flex flex-wrap items-center gap-2 md:flex-row"> <Button>Button</Button> <Button variant="outline" size="icon" aria-label="Submit"> <ArrowUpIcon /> </Button></div>Installation
Section titled “Installation” bunx bejamas add button npx bejamas add button pnpm dlx bejamas add button yarn dlx bejamas add button---/** * @component Button * @title Button * @description A clickable element for triggering actions or submitting forms. * * @preview * * <div class="flex flex-wrap items-center gap-2 md:flex-row"> * <Button>Button</Button> * <Button variant="outline" size="icon" aria-label="Submit"> * <ArrowUpIcon /> * </Button> * </div> * * @usage * * ```astro * --- * import Button from '@/ui/components/Button.astro'; * --- * * <Button>Click me</Button> * ``` * * ## Link * * You can use the `as` prop to render the component as an anchor. * * ```astro * --- * import Button from '@/ui/components/Button.astro'; * --- * * <Button as="a" href="https://bejamas.com">Click me</Button> * ``` * * @examples * * ### Variants * * <div class="flex flex-col items-start gap-8 sm:flex-row"> * <Button variant="default">Default</Button> * <Button variant="secondary">Secondary</Button> * <Button variant="outline">Outline</Button> * <Button variant="ghost">Ghost</Button> * <Button variant="destructive">Destructive</Button> * </div> * * ### Sizes * * <div class="flex flex-col items-start gap-8 sm:flex-row"> * <div class="flex items-start gap-2"> * <Button size="sm" variant="outline"> * Small * </Button> * <Button size="icon-sm" aria-label="Submit" variant="outline"> * <ArrowUpRightIcon /> * </Button> * </div> * <div class="flex items-start gap-2"> * <Button variant="outline">Default</Button> * <Button size="icon" aria-label="Submit" variant="outline"> * <ArrowUpRightIcon /> * </Button> * </div> * <div class="flex items-start gap-2"> * <Button variant="outline" size="lg"> * Large * </Button> * <Button size="icon-lg" aria-label="Submit" variant="outline"> * <ArrowUpRightIcon /> * </Button> * </div> * </div> * * ### With badge * * <Button variant="default"> * Click me * <Badge variant="secondary">Value</Badge> * </Button> * * ### Destructive * * <Button variant="destructive">Click me</Button> * * ### Outline * * <Button variant="outline">Click me</Button> * * ### Secondary * * <Button variant="secondary">Click me</Button> * * ### Ghost * * <Button variant="ghost">Click me</Button> * * ### Link * * <Button variant="link">Click me</Button> * * ### Default * * <Button>Click me</Button> * */
import type { HTMLTag, Polymorphic } from "astro/types";import { cva } from "class-variance-authority";import { cn } from "@bejamas/ui/lib/utils";
type Props = { as?: HTMLTag; variant?: | "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"; size?: "default" | "sm" | "lg" | "icon";};
const { as: Tag = "button", variant = "default", size = "default", class: className = "", ...props} = Astro.props as Props;
const buttonVariants = cva( "inline-flex ease-out duration-150 border-border items-center justify-center gap-2 whitespace-nowrap rounded-lg font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive active:scale-98", { variants: { variant: { default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", outline: "border shadow-xs hover:bg-accent hover:border-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-secondary", link: "text-accent underline-offset-4 hover:underline p-0", }, size: { default: "h-9 px-3 py-2 text-sm has-[.badge:last-child]:pr-1.5 has-[>svg]:px-2.5", sm: "h-8.5 text-sm rounded-lg gap-1.5 px-3 has-[>svg]:px-2", lg: "h-10 text-sm rounded-lg px-5 has-[>svg]:px-4 has-[.badge:last-child]:pr-3 [&_.badge:last-child]:ml-1.5", icon: "size-9", "icon-sm": "size-8.5", "icon-lg": "size-10", }, }, defaultVariants: { variant: "default", size: "default", }, },);---
<Tag class={cn(buttonVariants({ variant, size, className }))} {...props}> <slot /></Tag>---import Button from '@bejamas/ui/components/Button.astro';---
<Button>Click me</Button>You can use the as prop to render the component as an anchor.
---import Button from '@bejamas/ui/components/Button.astro';---
<Button as="a" href="https://bejamas.com">Click me</Button>| Prop | Type | Default |
|---|---|---|
as | HTMLTag | "button" |
variant | | "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "default" |
size | "default" | "sm" | "lg" | "icon" | "default" |
Examples
Section titled “Examples”Variants
Section titled “Variants”---import Button from '@bejamas/ui/components/Button.astro';---
<div class="flex flex-col items-start gap-8 sm:flex-row"> <Button variant="default">Default</Button> <Button variant="secondary">Secondary</Button> <Button variant="outline">Outline</Button> <Button variant="ghost">Ghost</Button> <Button variant="destructive">Destructive</Button></div>---import { ArrowUpRightIcon } from '@lucide/astro';
import Button from '@bejamas/ui/components/Button.astro';---
<div class="flex flex-col items-start gap-8 sm:flex-row"> <div class="flex items-start gap-2"> <Button size="sm" variant="outline"> Small </Button> <Button size="icon-sm" aria-label="Submit" variant="outline"> <ArrowUpRightIcon /> </Button> </div> <div class="flex items-start gap-2"> <Button variant="outline">Default</Button> <Button size="icon" aria-label="Submit" variant="outline"> <ArrowUpRightIcon /> </Button> </div> <div class="flex items-start gap-2"> <Button variant="outline" size="lg"> Large </Button> <Button size="icon-lg" aria-label="Submit" variant="outline"> <ArrowUpRightIcon /> </Button> </div></div>With badge
Section titled “With badge”---import Badge from '@bejamas/ui/components/Badge.astro';import Button from '@bejamas/ui/components/Button.astro';---
<Button variant="default"> Click me <Badge variant="secondary">Value</Badge></Button>Destructive
Section titled “Destructive”---import Button from '@bejamas/ui/components/Button.astro';---
<Button variant="destructive">Click me</Button>Outline
Section titled “Outline”---import Button from '@bejamas/ui/components/Button.astro';---
<Button variant="outline">Click me</Button>Secondary
Section titled “Secondary”---import Button from '@bejamas/ui/components/Button.astro';---
<Button variant="secondary">Click me</Button>---import Button from '@bejamas/ui/components/Button.astro';---
<Button variant="ghost">Click me</Button>---import Button from '@bejamas/ui/components/Button.astro';---
<Button variant="link">Click me</Button>Default
Section titled “Default”---import Button from '@bejamas/ui/components/Button.astro';---
<Button>Click me</Button>