# ItemButton

An interactive button component built on top of `Item` that provides all the layout and styling capabilities of Item with full button functionality. ItemButton supports actions, links, form submissions, and all the advanced features like hotkeys, tooltips, and selection states.

## When to Use

- For buttons that need structured content with icons, descriptions, or prefixes/suffixes
- When you need button functionality with the flexible layout capabilities of Item
- For interactive items in lists, menus, or toolbars that need consistent styling
- When building buttons that support features like keyboard shortcuts or overflow tooltips
- As an alternative to traditional buttons when you need more layout control

## Component

---

### Properties

- **`type`** `'primary' | 'outline' | 'outline-2' | 'clear'` — Visual type/variant of the button
- **`theme`** `'default' | 'danger' | 'success' | 'special'` — Color theme of the button
- **`size`** `'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'` (default: `medium`) — Size of the button (does not support `'inline'`)
- **`icon`** `ReactNode` — Icon displayed before the content
- **`rightIcon`** `ReactNode` — Icon displayed after the content
- **`prefix`** `ReactNode` — Content rendered before the label
- **`suffix`** `ReactNode` — Content rendered after the label
- **`hotkeys`** `string` — Keyboard shortcut that triggers the button (e.g., `"cmd+s"`, `"ctrl+alt+d"`)
- **`tooltip`** `boolean | string | object` — Tooltip configuration: string for simple text, `true` for auto overflow tooltips, or object for advanced config with optional `auto` property
- **`isDisabled`** `boolean` — Whether the button is disabled
- **`isSelected`** `boolean` — Whether the button shows as selected with a checkmark (pairs with `icon="checkmark"`)
- **`to`** `string` — URL for link behavior (makes button act as link)
- **`htmlType`** `'button' | 'submit' | 'reset'` — HTML button type attribute
- **`description`** `string` — Secondary text shown below the main content
- **`isLoading`** `boolean` — Whether the button shows loading state with disabled interaction
- **`actions`** `ReactNode` — Inline action buttons displayed on the right side. Use `ItemButton.Action` for consistent styling. Actions automatically inherit the parent button's `type` prop
- **`autoHideActions`** `boolean` — When true, actions are hidden by default and fade in on hover
- **`preserveActionsSpace`** `boolean` (default: `false`) — Preserve the actions width when hidden (only changes opacity, not layout)
- **`disableActionsFocus`** `boolean` (default: `false`) — Disable focus on action buttons by setting tabIndex to -1
- **`level`** `1 | 2 | 3 | 4 | 5 | 6` (default: `3`) — Heading level for the label element when type is "header" or "card"
- **`highlight`** `string` — String to highlight within children text
- **`highlightCaseSensitive`** `boolean` (default: `false`) — Whether highlight matching is case-sensitive
- **`shape`** `'card' | 'button' | 'sharp' | 'pill'` (default: `'button'`) — Shape of the button's border radius
- **`wrapperStyles`** `Styles` — Custom styles for the outer wrapper element when actions are present
- **`onPress`** `(e: PressEvent) => void` — Callback fired when button is pressed

Inherits from [Item](../content/Item.md).

### Base Properties

Supports [Base properties](../../BaseProperties.md)

### Modifiers

Inherits all modifiers from [Item](../content/Item.md) plus:

- **`disabled`** `boolean` — Applied when the button is disabled
- **`pressed`** `boolean` — Applied during button press interaction

## Variants

### Types

- `primary` - Primary button with prominent styling for main actions
- `outline` - Button with border outline; `isSelected` adds brand-tinted fill
- `clear` - Transparent button with minimal visual weight; `isSelected` adds brand-tinted fill
- `link` - Link-styled button that looks like a text link

### Themes

- `default` - Standard appearance with default colors
- `danger` - Red theme for destructive actions (delete, remove, etc.)
- `success` - Green theme for positive actions (save, confirm, etc.)
- `special` - Special theme with unique styling for standout actions

### Sizes

- `xsmall` - Extra small size for compact interfaces
- `small` - Small size for dense layouts
- `medium` - Default size for most use cases
- `large` - Large size for prominent actions
- `xlarge` - Extra large size for hero actions

## Examples

### Basic Button

```jsx
<ItemButton onPress={() => console.log('Clicked')}>Click me</ItemButton>
```

### Button with Icons

```jsx
<ItemButton
  icon={<IconFile />}
  rightIcon={<IconExternalLink />}
  onPress={handleOpen}
>
  Open File
</ItemButton>
```

### Link Button

```jsx
<ItemButton to="/docs">Go to Documentation</ItemButton>
```

### Button with Hotkey

```jsx
<ItemButton hotkeys="cmd+s" onPress={handleSave} type="primary">
  Save Document
</ItemButton>
```

### Form Submit Button

```jsx
<ItemButton htmlType="submit" type="primary" icon={<IconCheck />}>
  Submit Form
</ItemButton>
```

### Button with Selection State

```jsx
<ItemButton isSelected={isSelected} onPress={() => setIsSelected(!isSelected)}>
  Toggle Selection
</ItemButton>
```

### Button with Actions

ItemButton supports inline actions that appear on the right side. Use the `ItemButton.Action` compound component for consistent styling:

```jsx
<ItemButton
  icon={<IconFile />}
  actions={
    <>
      <ItemButton.Action
        icon={<IconEdit />}
        aria-label="Edit"
        onPress={handleEdit}
      />
      <ItemButton.Action
        icon={<IconTrash />}
        aria-label="Delete"
        onPress={handleDelete}
      />
    </>
  }
  onPress={handleOpen}
>
  Document with Actions
</ItemButton>
```

Actions automatically inherit the parent button's `type` prop and adjust their styling accordingly. The component reserves space for actions to prevent content overlap.

## Accessibility

### Keyboard Navigation

- `Tab` - Moves focus to the button
- `Space/Enter` - Activates the button
- Custom hotkeys - Trigger button action when hotkeys are specified
- `Escape` - Removes focus when pressed (standard browser behavior)

### Screen Reader Support

- Button announces as "button" to screen readers
- Link buttons announce as "link" when `to` prop is provided
- Button state is announced (pressed, disabled, selected)
- Hotkey information is included in accessible description

### ARIA Properties

- `aria-label` - Provides accessible label when text content isn't descriptive enough
- `aria-disabled` - Indicates disabled state
- `aria-pressed` - Indicates toggle state for toggle buttons
- `role` - Automatically set to "button" or "link" based on props

## Behaviour Inside Popovers

Like `Button`, an `ItemButton` press inside an open popover **dismisses
that popover** by default — popovers are transient surfaces and any action
inside them should close them. Modals/trays/fullscreen Dialogs are not
affected.

### Opt-outs

- **Automatic for popover triggers** — `MenuTrigger`, `DialogTrigger
type="popover"`, and the picker components (`FilterPicker`, `Picker`,
  `ComboBox`, `Select`) mark their trigger ItemButtons with
  `data-popover-trigger` so they don't dismiss the popover they themselves
  live in.
- **Manual via `data-popover-keep`** — add to the ItemButton (toggle) or
  any ancestor (whole subtree):
  ```jsx
  <ItemButton data-popover-keep onPress={() => setMode((m) => !m)}>
    Toggle Mode
  </ItemButton>
  ```
- **Custom non-Cube triggers** — call `useDismissParentPopover()` directly
  if you build a control on top of something other than `Button` /
  `ItemButton`.

The dismiss is dispatched via the EventBus, which defers with `setTimeout(0)`
— so synchronous `onPress` handlers (and the React state updates they
trigger) flush BEFORE the popover closes. This makes the "open a hoisted
modal from a popover footer" pattern work without flicker: the modal mounts
first, then the popover closes behind it.

## Best Practices

1. **Do**: Use clear, action-oriented text

   ```jsx
   <ItemButton onPress={handleSave} type="primary">
     Save Changes
   </ItemButton>
   ```

2. **Do**: Add hotkeys for frequently used actions

   ```jsx
   <ItemButton hotkeys="cmd+s" onPress={handleSave}>
     Save Document
   </ItemButton>
   ```

3. **Do**: Use appropriate button types for forms

   ```jsx
   <ItemButton htmlType="submit" type="primary">
     Submit Form
   </ItemButton>
   ```

4. **Do**: Use `ItemButton.Action` for inline actions

   ```jsx
   <ItemButton
     icon={<IconFile />}
     actions={
       <>
         <ItemButton.Action icon={<IconEdit />} aria-label="Edit" />
         <ItemButton.Action icon={<IconTrash />} aria-label="Delete" />
       </>
     }
     onPress={handleOpen}
   >
     Open Document
   </ItemButton>
   ```

5. **Don't**: Use vague or unclear button text

   ```jsx
   {
     /* Avoid this - unclear what "OK" does */
   }
   <ItemButton onPress={handleAction}>OK</ItemButton>;
   ```

6. **Don't**: Add too many actions (limit to 2-3 for clarity)

   ```jsx
   {
     /* Avoid this - too many action buttons */
   }
   <ItemButton
     actions={
       <>
         <ItemButton.Action icon={<IconEdit />} aria-label="Edit" />
         <ItemButton.Action icon={<IconCopy />} aria-label="Copy" />
         <ItemButton.Action icon={<IconShare />} aria-label="Share" />
         <ItemButton.Action icon={<IconTrash />} aria-label="Delete" />
       </>
     }
   >
     Button with too many actions
   </ItemButton>;
   ```

7. **Don't**: Overcrowd buttons with too many visual elements

   ```jsx
   {
     /* Avoid this - too many competing elements */
   }
   <ItemButton
     icon={<IconA />}
     rightIcon={<IconB />}
     prefix="Pre"
     suffix="Suf"
     description="Long description"
   >
     Overcrowded Button
   </ItemButton>;
   ```

8. **Accessibility**: Always ensure buttons have clear, descriptive labels, proper keyboard support, and provide `aria-label` for action buttons

## Integration with Forms

ItemButton integrates seamlessly with forms when using the `htmlType` prop:

```jsx
<form onSubmit={handleSubmit}>
  <TextInput name="email" label="Email" />
  <ItemButton htmlType="submit" type="primary">
    Sign In
  </ItemButton>
  <ItemButton htmlType="reset" type="outline">
    Clear Form
  </ItemButton>
</form>
```

## Related Components

- [Item](../content/Item.md) - The foundational component that ItemButton extends
- [ItemButton.Action](./ItemAction.md) - Action button component for inline actions (also available as `Item.Action`, `Menu.Item.Action`, etc.)
- [Button](./Button.md) - Traditional button component for simpler use cases
- [Link](./Link.md) - Text link component for navigation
- [Menu.Item](./Menu.md) - Menu item component that also uses Item
