Skip to main content

Button Components

Proton provides a variety of button components for different use cases, from basic buttons to specialized button groups and floating action buttons.

Button (from @proton/atoms)

The primary button component from the atoms package.

Basic Usage

import { Button } from '@proton/atoms/Button/Button';

const MyComponent = () => {
  return (
    <Button color="norm" onClick={() => console.log('Clicked')}>
      Click Me
    </Button>
  );
};

Props

color
string
Button color variant. Options: norm, weak, danger, warning, success, info
shape
string
Button shape variant. Options: solid, outline, ghost
size
string
Button size. Options: small, medium, large
fullWidth
boolean
Whether the button should take full width of its container
loading
boolean
Shows loading spinner and disables the button
disabled
boolean
Disables the button
icon
boolean
Renders as an icon button (square shape)

Examples

<Button color="norm">Normal</Button>
<Button color="weak">Weak</Button>
<Button color="danger">Danger</Button>
<Button color="warning">Warning</Button>
<Button color="success">Success</Button>

ButtonGroup

Groups multiple buttons together with consistent styling. Location: components/button/ButtonGroup.tsx

Usage

import { ButtonGroup } from '@proton/components/components/button/ButtonGroup';
import { Button } from '@proton/atoms/Button/Button';

const MyButtonGroup = () => {
  return (
    <ButtonGroup>
      <Button>First</Button>
      <Button>Second</Button>
      <Button>Third</Button>
    </ButtonGroup>
  );
};

Props

color
'norm' | 'weak'
Color scheme for all buttons in the group. Default: weak
shape
ButtonLikeShape
Shape for all buttons in the group. Default: outline
size
ButtonLikeSize
Size for all buttons in the group. Default: medium
separators
boolean
Show separators between buttons. Default: true
pill
boolean
Apply pill shape to the button group. Default: false
individualButtonColor
boolean
Allow individual buttons to override the group color. Default: false

Examples

<ButtonGroup>
  <Button>One</Button>
  <Button>Two</Button>
  <Button>Three</Button>
</ButtonGroup>

FloatingButton

A floating action button (FAB) for primary actions. Location: components/button/FloatingButton.tsx

Usage

import FloatingButton from '@proton/components/components/button/FloatingButton';
import { Icon } from '@proton/components';

const MyFAB = () => {
  return (
    <FloatingButton onClick={() => console.log('FAB clicked')}>
      <Icon name="plus" />
    </FloatingButton>
  );
};

Props

Extends ButtonProps from @proton/atoms/Button/Button.
title
string
Tooltip text for the button
className
string
Additional CSS classes

Example

<FloatingButton 
  title="Create new item"
  className="fixed bottom-4 right-4"
>
  <Icon name="plus" size={5} />
</FloatingButton>

FileButton

A button that triggers file input for file uploads. Location: components/button/FileButton.tsx

Usage

import FileButton from '@proton/components/components/button/FileButton';

const MyFileUpload = () => {
  const handleFileSelect = (event: ChangeEvent<HTMLInputElement>) => {
    const files = event.target.files;
    console.log('Selected files:', files);
  };

  return (
    <FileButton 
      onSelect={handleFileSelect}
      accept="image/*"
    >
      Upload Image
    </FileButton>
  );
};

SidebarExpandButton

Button for expanding/collapsing sidebar. Location: components/button/SidebarExpandButton.tsx

Usage

import SidebarExpandButton from '@proton/components/components/button/SidebarExpandButton';

const MySidebar = () => {
  const [expanded, setExpanded] = useState(false);

  return (
    <SidebarExpandButton 
      expanded={expanded}
      onClick={() => setExpanded(!expanded)}
    />
  );
};

Best Practices

Button Hierarchy

  1. Primary Action: Use color="norm" with shape="solid"
  2. Secondary Action: Use color="weak" or shape="outline"
  3. Destructive Action: Use color="danger"
<div className="flex gap-2">
  <Button color="norm" shape="solid">Save</Button>
  <Button color="weak" shape="outline">Cancel</Button>
</div>

Loading States

Show loading state during async operations:
const [loading, setLoading] = useState(false);

const handleSubmit = async () => {
  setLoading(true);
  try {
    await saveData();
  } finally {
    setLoading(false);
  }
};

return (
  <Button loading={loading} onClick={handleSubmit}>
    Save Changes
  </Button>
);

Accessibility

// Provide aria-label for icon-only buttons
<Button icon aria-label="Close dialog">
  <Icon name="cross" />
</Button>

// Use disabled state appropriately
<Button disabled={!isValid}>Submit</Button>

Source Code

View source:
  • Button: packages/components/components/button/
  • ButtonGroup: packages/components/components/button/ButtonGroup.tsx:1
  • FloatingButton: packages/components/components/button/FloatingButton.tsx:1

Build docs developers (and LLMs) love