Components
Button

Button

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

Import

import { Button } from '@nostromo/ui-core'
// or
import { Button } from '@nostromo/ui-core/button'

Usage

import { Button } from '@nostromo/ui-core'
 
export default function Example() {
  return (
    <Button variant="default" size="default">
      Click me
    </Button>
  )
}

Live Examples

Live Example
☀️
Copy
Storybook →
View Code
import { Button } from '@nostromo/ui-core' export default function ButtonDefault() { return <Button>Click me</Button> }...
Live Example
☀️
Copy
Storybook →
View Code
import { Button } from '@nostromo/ui-core' 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>...

Sizes

Live Example
☀️
Copy
Storybook →
View Code
import { Button } from '@nostromo/ui-core' 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