Icon button
A compact button with an icon and no text.
Props
icon
GoAIconType
Sets the icon.
size
IconSize
Sets the size of button.
Defaults to
medium.
theme
IconTheme
Sets the icon theme. 'outline' for stroked icons, 'filled' for solid icons.
Defaults to
outline.
variant
color | nocolor | light | dark | destructive
Styles the button to show color, light, dark or destructive action.
Defaults to
color.
title
string
Sets the title of the button.
testId
string
Sets a data-testid attribute for automated testing.
disabled
boolean
Disables the button.
Defaults to
false.
inverted
boolean
When true, inverts the icon colors for use on dark backgrounds.
Defaults to
false.
ariaLabel
string
Sets the aria-label of the button.
mt, mr, mb, ml
none | 3xs | 2xs | xs | s | m | l | xl | 2xl | 3xl | 4xl
Apply margin to the top, right, bottom, and/or left of the component.
Events
onClick
(event: Event) => void
_click
CustomEvent
Copy to clipboard
.token-block {
background-color: var(--goa-color-interactive-default);
height: 22px;
width: 24px;
border-radius: var(--goa-border-radius-s);
}const [isCopied, setIsCopied] = useState(false);
function copyCode() {
const codeToCopy = "$goa-color-interactive-default";
navigator.clipboard.writeText(codeToCopy).then(() => {
setIsCopied(true);
setTimeout(() => setIsCopied(false), 1000);
});
}<GoabBlock alignment="center">
<div className="token-block" />
<span>$goa-color-interactive-default</span>
<GoabTooltip content={isCopied ? "Copied" : "Copy?"} position="top">
<GoabIconButton icon="copy" onClick={copyCode} mt="2xs" />
</GoabTooltip>
</GoabBlock>.token-block {
background-color: var(--goa-color-interactive-default);
height: 22px;
width: 24px;
border-radius: var(--goa-border-radius-s);
}isCopied = false;
copyCode(): void {
const codeToCopy = "$goa-color-interactive-default";
navigator.clipboard.writeText(codeToCopy).then(() => {
this.isCopied = true;
setTimeout(() => this.isCopied = false, 1000);
});
}<goab-block alignment="center" gap="s">
<div class="token-block"></div>
<span>$goa-color-interactive-default</span>
<goab-tooltip [content]="isCopied ? 'Copied' : 'Copy?'" position="top">
<goab-icon-button icon="copy" (onClick)="copyCode()" mt="2xs"></goab-icon-button>
</goab-tooltip>
</goab-block>.token-block {
background-color: var(--goa-color-interactive-default);
height: 22px;
width: 24px;
border-radius: var(--goa-border-radius-s);
}const copyBtn = document.getElementById('copy-btn');
const tooltip = document.getElementById('copy-tooltip');
function copyCode() {
const codeToCopy = "$goa-color-interactive-default";
navigator.clipboard.writeText(codeToCopy).then(() => {
tooltip.setAttribute('content', 'Copied');
setTimeout(() => {
tooltip.setAttribute('content', 'Copy?');
}, 1000);
});
}
copyBtn.addEventListener('_click', copyCode);<goa-block alignment="center">
<div class="token-block"></div>
<span>$goa-color-interactive-default</span>
<goa-tooltip id="copy-tooltip" content="Copy?" position="top">
<goa-icon-button id="copy-btn" icon="copy" mt="2xs"></goa-icon-button>
</goa-tooltip>
</goa-block>Show a label on an icon only button
<GoabButtonGroup alignment="start">
<GoabTooltip content="Edit">
<GoabIconButton icon="pencil" ariaLabel="Edit" />
</GoabTooltip>
<GoabTooltip content="Alerts">
<GoabIconButton icon="notifications" ariaLabel="Alerts" />
</GoabTooltip>
<GoabTooltip content="Settings">
<GoabIconButton icon="settings" ariaLabel="Settings" />
</GoabTooltip>
</GoabButtonGroup><goab-button-group alignment="start">
<goab-tooltip content="Edit">
<goab-icon-button icon="pencil" ariaLabel="Edit"></goab-icon-button>
</goab-tooltip>
<goab-tooltip content="Alerts">
<goab-icon-button icon="notifications" ariaLabel="Alerts"></goab-icon-button>
</goab-tooltip>
<goab-tooltip content="Settings">
<goab-icon-button icon="settings" ariaLabel="Settings"></goab-icon-button>
</goab-tooltip>
</goab-button-group><goa-button-group alignment="start">
<goa-tooltip content="Edit">
<goa-icon-button icon="pencil" aria-label="Edit"></goa-icon-button>
</goa-tooltip>
<goa-tooltip content="Alerts">
<goa-icon-button icon="notifications" aria-label="Alerts"></goa-icon-button>
</goa-tooltip>
<goa-tooltip content="Settings">
<goa-icon-button icon="settings" aria-label="Settings"></goa-icon-button>
</goa-tooltip>
</goa-button-group>Show multiple actions in a compact table
const rows = [
{ status: "information", statusText: "In progress", name: "Darlene Robertson", id: 45904 },
{ status: "dark", statusText: "Inactive", name: "Floyd Miles", id: 47838 },
{ status: "success", statusText: "Active", name: "Kathryn Murphy", id: 34343 },
{ status: "important", statusText: "Recent", name: "Annette Black", id: 89897 },
{ status: "success", statusText: "Active", name: "Esther Howard", id: 12323 },
{ status: "success", statusText: "Active", name: "Jane Cooper", id: 56565 },
];<GoabxTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th style={{ textAlign: "right" }}>Id Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Edit | Flag | Send</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.id}>
<td>
<GoabxBadge
type={row.status as "information" | "dark" | "success" | "important"}
content={row.statusText}
icon={false}
/>
</td>
<td>{row.name}</td>
<td className="goa-table-number-column">{row.id}</td>
<td>
<GoabBlock>
<GoabIconButton size="small" icon="pencil" ariaLabel="Edit" />
<GoabIconButton size="small" icon="flag" ariaLabel="Flag" />
<GoabIconButton size="small" icon="mail" ariaLabel="Send" />
</GoabBlock>
</td>
</tr>
))}
</tbody>
</GoabxTable>rows: TableRow[] = [
{ status: "information", statusText: "In progress", name: "Darlene Robertson", id: 45904 },
{ status: "dark", statusText: "Inactive", name: "Floyd Miles", id: 47838 },
{ status: "success", statusText: "Active", name: "Kathryn Murphy", id: 34343 },
{ status: "important", statusText: "Recent", name: "Annette Black", id: 89897 },
{ status: "success", statusText: "Active", name: "Esther Howard", id: 12323 },
{ status: "success", statusText: "Active", name: "Jane Cooper", id: 56565 },
];<goabx-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th style="text-align: right">Id Number</th>
<th style="width: 1%; white-space: nowrap">Edit | Flag | Send</th>
</tr>
</thead>
<tbody>
@for (row of rows; track row.id) {
<tr>
<td>
<goabx-badge [type]="row.status" [content]="row.statusText" [icon]="false"></goabx-badge>
</td>
<td>{{ row.name }}</td>
<td class="goa-table-number-column">{{ row.id }}</td>
<td>
<goab-block>
<goab-icon-button size="small" icon="pencil" ariaLabel="Edit"></goab-icon-button>
<goab-icon-button size="small" icon="flag" ariaLabel="Flag"></goab-icon-button>
<goab-icon-button size="small" icon="mail" ariaLabel="Send"></goab-icon-button>
</goab-block>
</td>
</tr>
}
</tbody>
</goabx-table><goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th style="text-align: right">Id Number</th>
<th style="width: 1%; white-space: nowrap">Edit | Flag | Send</th>
</tr>
</thead>
<tbody>
<tr>
<td><goa-badge version="2" type="information" content="In progress" icon="false"></goa-badge></td>
<td>Darlene Robertson</td>
<td class="goa-table-number-column">45904</td>
<td>
<goa-block>
<goa-icon-button size="small" icon="pencil" arialabel="Edit"></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td><goa-badge version="2" type="dark" content="Inactive" icon="false"></goa-badge></td>
<td>Floyd Miles</td>
<td class="goa-table-number-column">47838</td>
<td>
<goa-block>
<goa-icon-button size="small" icon="pencil" arialabel="Edit"></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td><goa-badge version="2" type="success" content="Active" icon="false"></goa-badge></td>
<td>Kathryn Murphy</td>
<td class="goa-table-number-column">34343</td>
<td>
<goa-block>
<goa-icon-button size="small" icon="pencil" arialabel="Edit"></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td><goa-badge version="2" type="important" content="Recent" icon="false"></goa-badge></td>
<td>Annette Black</td>
<td class="goa-table-number-column">89897</td>
<td>
<goa-block>
<goa-icon-button size="small" icon="pencil" arialabel="Edit"></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td><goa-badge version="2" type="success" content="Active" icon="false"></goa-badge></td>
<td>Esther Howard</td>
<td class="goa-table-number-column">12323</td>
<td>
<goa-block>
<goa-icon-button size="small" icon="pencil" arialabel="Edit"></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td><goa-badge version="2" type="success" content="Active" icon="false"></goa-badge></td>
<td>Jane Cooper</td>
<td class="goa-table-number-column">56565</td>
<td>
<goa-block>
<goa-icon-button size="small" icon="pencil" arialabel="Edit"></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
</tbody>
</table>
</goa-table>States
Only use disabled buttons if research shows it makes the user interface easier to understand.
Consider removing options that are unavailable or not applicable. Show actions that are only relevant and useful to the user at a given time.
Don't
Avoid using disabled buttons. They have poor contrast and can confuse users.
When you must disable a button or input:
- Provide nearby text explaining what needs to happen first
- Consider showing the element enabled with validation on submit instead
- Use aria-describedby to link the disabled element to explanatory text
Don't
Don't disable buttons or inputs without explaining why. Disabled controls can be confusing and users may not understand why they can't interact with an element.
Types
Don't
Don't use Button for simple navigation (use Link), toggling state (use Toggle or Checkbox), or minor utility functions (use Icon Button).
Positioning
Do
Use a button group when putting multiple buttons together.
Screen Readers
Icon-only interactive elements must have an accessible label so screen reader users understand their purpose.
For IconButton: The ariaLabel prop is required.
// Good - describes the action
<GoabIconButton icon="trash" ariaLabel="Delete item" />
// Bad - no label for screen readers
<GoabIconButton icon="trash" />
For Badge with icon only: Provide ariaLabel when there’s no visible text.
<GoabBadge icon="warning" ariaLabel="Warning" type="important" />
For Icon: Use ariaLabel when the icon conveys meaning, not just decoration.
The label should describe:
- What action happens (for buttons): “Delete”, “Edit”, “Close”
- What the icon represents (for informational icons): “Warning”, “Success”
Don't
Don't use icon-only elements without an accessible label
Do
Icon-only buttons must include a descriptive label for screen readers.
Focus
Don't
Don't focus on just the icon within a button. Focus the button as a whole.