Forms
Button.
Orange primary actions and quiet outlined secondaries, with sizes, icons and link rendering.
import { ArrowUpRight } from "lucide-react";
import { Button } from "@/components/ui/button";
export default function ButtonDemo() {
return (
<div className="flex flex-wrap items-center gap-3">
<Button>
Make yourself at home <ArrowUpRight />
</Button>
<Button variant="secondary">Explore the network</Button>
</div>
);
}Installation#
With the CLI
$npx lanterncn add buttonThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/button. See Installation if your project is not set up yet.
Manually
Install the dependencies
npm install radix-ui class-variance-authorityCopy the source into your project
components/ui/button.tsximport * as React from "react"; import { cva, type VariantProps } from "class-variance-authority"; import { Slot } from "radix-ui"; import { cn } from "@/lib/utils"; const buttonVariants = cva( "inline-flex shrink-0 cursor-pointer items-center justify-center gap-2.5 whitespace-nowrap rounded-md border border-transparent text-[13px] font-semibold transition-[background-color,border-color,color,transform] outline-none select-none active:translate-y-px focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-40 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-[#f8b981]", secondary: "border-[#566151] bg-transparent text-foreground hover:border-muted-foreground hover:bg-secondary", outline: "border-input bg-transparent text-foreground hover:bg-secondary", ghost: "text-muted-foreground hover:bg-secondary hover:text-foreground", destructive: "border-destructive bg-transparent text-destructive hover:bg-destructive/12", success: "bg-success text-success-foreground hover:bg-success/85", link: "h-auto px-0 text-primary underline-offset-4 hover:underline active:translate-y-0", }, size: { sm: "h-8 px-3 text-xs", default: "h-10 px-4", lg: "h-12 px-5", icon: "size-10", "icon-sm": "size-8", }, }, defaultVariants: { variant: "default", size: "default" }, }, ); function Button({ className, variant, size, asChild = false, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & { asChild?: boolean }) { const Comp = asChild ? Slot.Root : "button"; return <Comp data-slot="button" className={cn(buttonVariants({ variant, size, className }))} {...props} />; } export { Button, buttonVariants };Update the import paths to match your project
The source imports
cnfrom@/lib/utils.
Usage#
import { Button } from "@/components/ui/button";<Button variant="secondary">Explore the network</Button>Examples#
Variants
import { Button } from "@/components/ui/button";
export default function ButtonVariants() {
return (
<div className="flex flex-wrap items-center gap-3">
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="success">Success</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="link">Link</Button>
</div>
);
}Sizes
import { Plus, Settings } from "lucide-react";
import { Button } from "@/components/ui/button";
export default function ButtonSizes() {
return (
<div className="flex flex-wrap items-center gap-3">
<Button size="sm">Small</Button>
<Button>Default</Button>
<Button size="lg">Large</Button>
<Button size="icon" variant="outline" aria-label="Add">
<Plus />
</Button>
<Button size="icon-sm" variant="ghost" aria-label="Settings">
<Settings />
</Button>
</div>
);
}Loading, disabled and as a link
import { Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
export default function ButtonStates() {
return (
<div className="flex flex-wrap items-center gap-3">
<Button disabled>
<Loader2 className="animate-spin" /> Publishing
</Button>
<Button variant="secondary" disabled>
Disabled
</Button>
<Button variant="secondary" asChild>
<a href="#">As a link</a>
</Button>
</div>
);
}