ui / actions
PREVIEW READYButton
Four restrained action variants with loading, size, and disabled states.
INSTALL / SOURCE REGISTRY
Add Button to your project
The command adds the component source and its DesignOS base dependency.
$
pnpm dlx shadcn@latest add https://designos.h4rithd.com/r/button.jsonregistry/default/ui/button.tsx
import * as React from "react"
import { LoaderCircle } from "lucide-react"
import { clsx as cn } from "clsx"
import "@/components/designos/designos.css"
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: "primary" | "secondary" | "ghost" | "danger"
size?: "sm" | "md" | "lg"
loading?: boolean
}
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = "primary", size = "md", loading, disabled, children, ...props }, ref) => (
<button
ref={ref}
className={cn("dos-button", variant !== "primary" && `dos-button--${variant}`, size !== "md" && `dos-button--${size}`, className)}
disabled={disabled || loading}
aria-busy={loading || undefined}
{...props}
>
{loading && <LoaderCircle aria-hidden="true" className="dos-spin" />}
{children}
</button>
),
)
Button.displayName = "Button"
Component contract
- Source-owned after installation
- Dark and light theme variables
- Keyboard and visible-focus behavior
- Reduced-motion fallback
- Responsive from 320px upward
- IBM Plex Sans + JetBrains Mono hierarchy