# Icon Button (/components/actions/icon-button)



`IconButton` triggers a familiar compact action, such as closing a panel, deleting a row, or adding
an item. Give every icon button an accessible name because it has no visible label.

apps/docs/src/examples/icon-button/basic.tsx

```tsx
import { IconButton } from '@luke-ui/react/icon-button';

export default () => {
	return <IconButton aria-label="Add item" icon="add" />;
};
```

## Size [#size]

`medium` is the default. Use `small` for compact toolbars and dense row actions. Keep controls in a
group at the same size.

apps/docs/src/examples/icon-button/size.tsx

```tsx
import { IconButton } from '@luke-ui/react/icon-button';
import { Comparison, ComparisonItem } from '#docs/comparison';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Small">
				<IconButton aria-label="Example action" icon="search" size="small" />
			</ComparisonItem>
			<ComparisonItem label="Medium">
				<IconButton aria-label="Example action" icon="search" size="medium" />
			</ComparisonItem>
		</Comparison>
	);
};
```

## Appearance [#appearance]

`IconButton` uses the same `appearance` options as [`Button`](/components/actions/button). `solid`
is the default. Choose `subtle` or `ghost` when a secondary control needs less emphasis.

apps/docs/src/examples/icon-button/appearance.tsx

```tsx
import { IconButton } from '@luke-ui/react/icon-button';
import { Comparison, ComparisonItem } from '#docs/comparison';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Solid">
				<IconButton appearance="solid" aria-label="Example action" icon="bookOpen" />
			</ComparisonItem>
			<ComparisonItem label="Subtle">
				<IconButton appearance="subtle" aria-label="Example action" icon="bookOpen" />
			</ComparisonItem>
			<ComparisonItem label="Ghost">
				<IconButton appearance="ghost" aria-label="Example action" icon="bookOpen" />
			</ComparisonItem>
		</Comparison>
	);
};
```

## Tone [#tone]

Use `tone` to communicate intent. `neutral` is the default, `accent` identifies a primary action,
and `danger` marks a destructive one.

apps/docs/src/examples/icon-button/tones.tsx

```tsx
import { IconButton } from '@luke-ui/react/icon-button';
import { Comparison, ComparisonItem } from '#docs/comparison';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Neutral">
				<IconButton aria-label="Example action" icon="search" tone="neutral" />
			</ComparisonItem>
			<ComparisonItem label="Accent">
				<IconButton aria-label="Example action" icon="search" tone="accent" />
			</ComparisonItem>
			<ComparisonItem label="Danger">
				<IconButton aria-label="Example action" icon="search" tone="danger" />
			</ComparisonItem>
		</Comparison>
	);
};
```

## Pending and Actions [#pending-and-actions]

`IconButton` uses the same pending and Action behaviour as [`Button`](/components/actions/button).
See Button’s [Pending and Actions](/components/actions/button#pending-and-actions) guidance.

apps/docs/src/examples/icon-button/pending.tsx

```tsx
import { IconButton } from '@luke-ui/react/icon-button';

export default () => {
	return <IconButton aria-label="Save changes" icon="check" isPending />;
};
```

## Disabled [#disabled]

Set `isDisabled` when the action is unavailable. Disabled controls cannot receive focus or respond
to presses.

apps/docs/src/examples/icon-button/disabled.tsx

```tsx
import { IconButton } from '@luke-ui/react/icon-button';

export default () => {
	return <IconButton aria-label="Search" icon="search" isDisabled />;
};
```

## Accessibility [#accessibility]

Provide `aria-label` or `aria-labelledby` for every icon button. Name the action, not the icon. Use
a labelled [`Button`](/components/actions/button) when the icon is unfamiliar or visible text would
make the action clearer.

## API [#api]

<ComponentPropsTable
  id="type-table-icon-button.tsx-IconButtonProps"
  type="{
  &#x22;id&#x22;: &#x22;icon-button.tsx-IconButtonProps&#x22;,
  &#x22;name&#x22;: &#x22;IconButtonProps&#x22;,
  &#x22;description&#x22;: &#x22;Props for `IconButton`.&#x22;,
  &#x22;entries&#x22;: [
    {
      &#x22;name&#x22;: &#x22;icon&#x22;,
      &#x22;description&#x22;: &#x22;Icon name from the generated icon set.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;\&#x22;add\&#x22; | \&#x22;arrowDown\&#x22; | \&#x22;arrowLeft\&#x22; | \&#x22;arrowRight\&#x22; | \&#x22;arrowUp\&#x22; | \&#x22;bookOpen\&#x22; | \&#x22;check\&#x22; | \&#x22;checkCircle\&#x22; | \&#x22;chevronDown\&#x22; | \&#x22;chevronLeft\&#x22; | \&#x22;chevronRight\&#x22; | \&#x22;chevronUp\&#x22; | \&#x22;circleHalf\&#x22; | \&#x22;close\&#x22; | \&#x22;closeCircle\&#x22; | \&#x22;codeBlock\&#x22; | \&#x22;copy\&#x22; | \&#x22;delete\&#x22; | \&#x22;edit\&#x22; | \&#x22;exclamationTriangle\&#x22; | \&#x22;expand\&#x22; | \&#x22;externalLink\&#x22; | \&#x22;minimize\&#x22; | \&#x22;mobilePhone\&#x22; | \&#x22;monitor\&#x22; | \&#x22;moon\&#x22; | \&#x22;search\&#x22; | \&#x22;sun\&#x22;&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: true,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;children&#x22;,
      &#x22;description&#x22;: &#x22;The children of the component. A function may be provided to alter the children based on\ncomponent state.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;ChildrenOrFunction<ButtonRenderProps>&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;ChildrenOrFunction<object>&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onPressStart&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a press interaction starts.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: PressEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onPressEnd&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a press interaction ends, either\nover the target or when the pointer leaves the target.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: PressEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onPressChange&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when the press state changes.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((isPressed: boolean) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onPressUp&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a press is released over the target, regardless of\nwhether it started on the target or not.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: PressEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;autoFocus&#x22;,
      &#x22;description&#x22;: &#x22;Whether the element should receive focus on render.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onFocus&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when the element receives focus.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: React.FocusEvent<Element, Element>) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onBlur&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when the element loses focus.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: React.FocusEvent<Element, Element>) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onFocusChange&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when the element's focus status changes.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((isFocused: boolean) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onKeyDown&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a key is pressed.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: KeyboardEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onKeyUp&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a key is released.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: KeyboardEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;id&#x22;,
      &#x22;description&#x22;: &#x22;The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;aria-label&#x22;,
      &#x22;description&#x22;: &#x22;Defines a string value that labels the current element.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;aria-labelledby&#x22;,
      &#x22;description&#x22;: &#x22;Identifies the element (or elements) that labels the current element.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;aria-describedby&#x22;,
      &#x22;description&#x22;: &#x22;Identifies the element (or elements) that describes the object.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;aria-details&#x22;,
      &#x22;description&#x22;: &#x22;Identifies the element (or elements) that provide a detailed, extended description for the\nobject.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onHoverStart&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a hover interaction starts.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: HoverEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onHoverEnd&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when a hover interaction ends.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: HoverEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onHoverChange&#x22;,
      &#x22;description&#x22;: &#x22;Handler that is called when the hover state changes.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((isHovering: boolean) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;slot&#x22;,
      &#x22;description&#x22;: &#x22;A slot name for the component. Slots allow the component to receive props from a parent\ncomponent. An explicit `null` value indicates that the local props completely override all\nprops received from a parent.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;string | null | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;render&#x22;,
      &#x22;description&#x22;: &#x22;Overrides the default DOM element with a custom render function.\nThis allows rendering existing components with built-in styles and behaviors\nsuch as router links, animation libraries, and pre-styled components.\n\nRequirements:\n\n- You must render the expected element type (e.g. if `<button>` is expected, you cannot render an\n  `<a>`).\n- Only a single root DOM element can be rendered (no fragments).\n- You must pass through props and ref to the underlying DOM element, merging with your own prop\n  as appropriate.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;DOMRenderFunction<\&#x22;button\&#x22;, ButtonRenderProps> | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;DOMRenderFunction<\&#x22;button\&#x22;, object>&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;appearance&#x22;,
      &#x22;description&#x22;: &#x22;Visual emphasis.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'solid'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;solid\&#x22; | \&#x22;ghost\&#x22; | \&#x22;subtle\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;tone&#x22;,
      &#x22;description&#x22;: &#x22;Visual tone. Controls colour scheme.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'neutral'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;neutral\&#x22; | \&#x22;accent\&#x22; | \&#x22;danger\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;isPending&#x22;,
      &#x22;description&#x22;: &#x22;Externally owned pending state. When true, the button is non-interactive and shows a spinner\nimmediately. Prefer `pressAction` for IconButton-owned operations.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;false&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;pressAction&#x22;,
      &#x22;description&#x22;: &#x22;IconButton-owned operation run as a React Action. The button becomes pending automatically\nuntil the Action settles. `onPress` handles the interaction. `pressAction` performs the\nresulting operation.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;PressAction | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;PressAction&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;size&#x22;,
      &#x22;description&#x22;: &#x22;Sets the button size.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'medium'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;\&#x22;small\&#x22; | \&#x22;medium\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;isDisabled&#x22;,
      &#x22;description&#x22;: &#x22;Whether the button is disabled. Disabled buttons can't be focused or pressed.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;false&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;onPress&#x22;,
      &#x22;description&#x22;: &#x22;Press handler. Called on click, Enter, or Space.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;((e: PressEvent) => void) | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;function&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;type&#x22;,
      &#x22;description&#x22;: &#x22;HTML button type.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;\&#x22;button\&#x22; | \&#x22;reset\&#x22; | \&#x22;submit\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;deprecated&#x22;: false,
      &#x22;description&#x22;: &#x22;`IconButtonProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.&#x22;,
      &#x22;name&#x22;: &#x22;__nativePropsForwarding&#x22;,
      &#x22;required&#x22;: true,
      &#x22;simplifiedType&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;&#x22;
    }
  ]
}"
/>
