UNPKG

@neynar/ui

Version:

React UI component library built on shadcn/ui and Tailwind CSS

281 lines (244 loc) 6.82 kB
# Button **Type**: component Button - A versatile, accessible button component with multiple style variants A fundamental UI element built on Radix UI's Slot primitive that supports extensive customization through variants, composition patterns, and comprehensive accessibility features. The component automatically handles icon styling, focus management, form integration, and can be rendered as other elements using the asChild pattern. ## JSX Usage ```jsx import { Button } from '@neynar/ui'; <Button variant={value} size={value} asChild={true} className="value" disabled={true} type={value} onClick={handleClick} onFocus={handleFocus} onBlur={handleBlur} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} "aria-label"="value" "aria-describedby"="value" "aria-invalid"={value} "aria-expanded"={value} "aria-controls"="value" "aria-pressed"={value} tabIndex={0} autoFocus={true} form="value" formAction={() => {}} formEncType="value" formMethod="value" formNoValidate={true} formTarget="value" name="value" value={value} ref={value} > {/* Your content here */} </Button> ``` ## Component Props ### variant - **Type**: `| "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"` - **Required**: No - **Description**: No description available ### size - **Type**: `"default" | "sm" | "lg" | "icon"` - **Required**: No - **Description**: No description available ### asChild - **Type**: `boolean` - **Required**: No - **Description**: No description available ### children - **Type**: `React.ReactNode` - **Required**: No - **Description**: No description available ### className - **Type**: `string` - **Required**: No - **Description**: No description available ### disabled - **Type**: `boolean` - **Required**: No - **Description**: No description available ### type - **Type**: `"button" | "submit" | "reset"` - **Required**: No - **Description**: No description available ### onClick - **Type**: `React.MouseEventHandler<HTMLButtonElement>` - **Required**: No - **Description**: No description available ### onFocus - **Type**: `React.FocusEventHandler<HTMLButtonElement>` - **Required**: No - **Description**: No description available ### onBlur - **Type**: `React.FocusEventHandler<HTMLButtonElement>` - **Required**: No - **Description**: No description available ### onMouseEnter - **Type**: `React.MouseEventHandler<HTMLButtonElement>` - **Required**: No - **Description**: No description available ### onMouseLeave - **Type**: `React.MouseEventHandler<HTMLButtonElement>` - **Required**: No - **Description**: No description available ### "aria-label" - **Type**: `string` - **Required**: No - **Description**: No description available ### "aria-describedby" - **Type**: `string` - **Required**: No - **Description**: No description available ### "aria-invalid" - **Type**: `boolean | "false" | "true" | "grammar" | "spelling"` - **Required**: No - **Description**: No description available ### "aria-expanded" - **Type**: `React.AriaAttributes['aria-expanded']` - **Required**: No - **Description**: No description available ### "aria-controls" - **Type**: `string` - **Required**: No - **Description**: No description available ### "aria-pressed" - **Type**: `boolean | "false" | "true" | "mixed"` - **Required**: No - **Description**: No description available ### tabIndex - **Type**: `number` - **Required**: No - **Description**: No description available ### autoFocus - **Type**: `boolean` - **Required**: No - **Description**: No description available ### form - **Type**: `string` - **Required**: No - **Description**: No description available ### formAction - **Type**: `string | ((formData: FormData) => void | Promise<void>)` - **Required**: No - **Description**: No description available ### formEncType - **Type**: `string` - **Required**: No - **Description**: No description available ### formMethod - **Type**: `string` - **Required**: No - **Description**: No description available ### formNoValidate - **Type**: `boolean` - **Required**: No - **Description**: No description available ### formTarget - **Type**: `string` - **Required**: No - **Description**: No description available ### name - **Type**: `string` - **Required**: No - **Description**: No description available ### value - **Type**: `string | ReadonlyArray<string> | number` - **Required**: No - **Description**: No description available ### ref - **Type**: `React.Ref<HTMLButtonElement>` - **Required**: No - **Description**: No description available ## Examples ### Example 1 ```tsx // Basic usage with different variants <Button>Default Button</Button> <Button variant="destructive">Delete Item</Button> <Button variant="outline" size="lg">Large Outline</Button> <Button variant="ghost" size="sm">Small Ghost</Button> <Button variant="link">Link Button</Button> ``` ### Example 2 ```tsx // Icon usage (automatically styled with proper spacing) import { Download, ArrowRight, Plus, Trash2 } from "lucide-react"; <Button> <Download className="mr-2" /> Download File </Button> <Button variant="outline"> Continue <ArrowRight className="ml-2" /> </Button> // Icon-only button (always include aria-label) <Button size="icon" aria-label="Add new item"> <Plus /> </Button> <Button size="icon" variant="destructive" aria-label="Delete item"> <Trash2 /> </Button> ``` ### Example 3 ```tsx // Composition with asChild (render as different elements) import Link from "next/link"; import { ExternalLink } from "lucide-react"; <Button asChild> <Link href="/dashboard">Go to Dashboard</Link> </Button> <Button asChild variant="outline"> <a href="https://example.com" target="_blank" rel="noopener noreferrer"> External Link <ExternalLink className="ml-2 h-4 w-4" /> </a> </Button> ``` ### Example 4 ```tsx // Form integration and states <Button type="submit" disabled={isSubmitting}> {isSubmitting ? "Submitting..." : "Submit Form"} </Button> <Button variant="destructive" onClick={() => handleDelete()} aria-describedby="delete-warning" > Delete Account </Button> <p id="delete-warning" className="sr-only"> This action cannot be undone </p> // Toggle button with pressed state <Button variant="outline" aria-pressed={isToggled} onClick={() => setIsToggled(!isToggled)} > {isToggled ? "Enabled" : "Disabled"} </Button> ``` ### Example 5 ```tsx // Loading states and advanced usage import { Loader2, Save } from "lucide-react"; <Button disabled={isLoading}> {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />} {isLoading ? "Saving..." : "Save Changes"} </Button> // With custom styling <Button className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600" size="lg" > Gradient Button </Button> ```