Skip to Content

Button

The Button component provides you with different button variants and sizes.

Live Examples

Live Example
☀️
Copy
View Code
import { Button } from '@jarllyng/nostromo' export default function ButtonDefault() { return <Button>Click me</Button> }...
Live Example
☀️
Copy
View Code
import { Button } from '@jarllyng/nostromo' export default function ButtonExamples() { return ( <div className="flex flex-wrap gap-4"> <Button variant="default">Default</Button> <Button variant="secondary">Secondary</Button> <Button variant="destructive">Destructive</Button> <Button variant="outline">Outline</Button> <Button variant="ghost">Ghost</Button>...

Import

import { Button } from "@jarllyng/nostromo"; // or import { Button } from "@jarllyng/nostromo/button";

Usage

import { Button } from "@jarllyng/nostromo"; export default function Example() { return ( <Button variant="default" size="default"> Click me </Button> ); }

Sizes

Live Example
☀️
Copy
View Code
import { Button } from '@jarllyng/nostromo' export default function ButtonSizes() { return ( <div className="space-x-4"> <Button size="sm">Small</Button> <Button size="default">Default</Button> <Button size="lg">Large</Button> </div> )...

Accessibility

Keyboard Navigation

  • Enter/Space: Activates the button
  • Tab: Moves focus to the button
  • Escape: Closes any associated dialogs or menus

ARIA Attributes

  • role=“button”: Identifies the element as a button
  • aria-disabled: Indicates when the button is disabled
  • aria-pressed: For toggle buttons (when applicable)

Focus Management

  • Visible focus indicator: Clear visual focus state
  • Focus trap: Prevents focus from escaping modal contexts
  • Focus restoration: Returns focus to trigger element

Screen Reader Support

  • Semantic HTML: Uses proper <button> element
  • Descriptive text: Clear button labels and descriptions
  • State announcements: Disabled and loading states are announced

Examples

// Accessible button with proper labeling <Button aria-label="Close dialog"> <XIcon /> </Button> // Button with loading state (recommended approach) <Button loading={isLoading} loadingText="Saving..." aria-describedby="loading-text"> Save </Button> <div id="loading-text" className="sr-only"> Please wait while your changes are saved </div> // Button with success/error feedback after action <Button state={saveResult === 'success' ? 'success' : saveResult === 'error' ? 'error' : 'default'}> {saveResult === 'success' ? 'Saved!' : saveResult === 'error' ? 'Failed' : 'Save'} </Button> // Button in form - use type="button" to prevent form submission <Button type="button" onClick={handleCancel}> Cancel </Button> <Button type="submit"> Submit </Button>

Best Practices

Do ✅

  • Use type="button" for buttons that don’t submit forms
  • Use type="submit" for form submission buttons
  • Provide aria-label for icon-only buttons
  • Use loading prop for async operations (shows spinner automatically)
  • Use state="success" or state="error" for post-action feedback
  • Use disabled prop to prevent interactions

Don’t ❌

  • Don’t use buttons for navigation (use links instead)
  • Don’t disable buttons without providing feedback
  • Don’t forget to handle loading states in forms
  • Don’t use buttons without accessible labels
  • Don’t use both loading={true} and state="loading" together (use loading prop instead)
  • Don’t use both loading={true} and state="loading" together (use loading prop instead)

Props

PropTypeDefaultRequiredDescription
variant"default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "subtle""default"NoVisual variant of the button
size"sm" | "default" | "lg" | "xl" | "icon""default"NoSize of the button
state"default" | "loading" | "success" | "error""default"NoVisual state of the button. Note: If loading is true, this prop is ignored and state becomes “loading”. Use state="success" or state="error" for post-action feedback.
loadingbooleanfalseNoWhether the button is in a loading state. When true, automatically sets state to “loading” and shows a spinner.
loadingTextstringundefinedNoText to display when loading is true. If not provided, the button’s children will be shown.
disabledbooleanfalseNoWhether the button is disabled
type"button" | "submit" | "reset""button"NoHTML button type attribute
onClick(event: React.MouseEvent<HTMLButtonElement>) => voidundefinedNoClick event handler
asChildbooleanfalseNoRender as child element (for composition)
classNamestringundefinedNoAdditional CSS classes
childrenReact.ReactNodeundefinedNoButton content

Standard HTML Button Props

The Button component extends all standard HTML button attributes, including:

  • id, name, value, form, formAction, formEncType, formMethod, formNoValidate, formTarget
  • aria-* attributes for accessibility
  • data-* attributes for custom data
  • All other standard HTML button attributes
Last updated on