# Action Swap

Building blocks for swapping a label or icon in place: the old one fades as the new one appears, plainly, with a small lift or letter by letter. Includes button, text, icon and multi-state versions.

> Composed · Free · Signature — React Native, Expo Go compatible.

## Install

```bash
npx @lumioui/cli add action-swap
```

## Import

```tsx
import { ActionSwapText, ActionSwapIcon, ActionSwapButton, ActionSwap } from "@/components/ui/action-swap/action-swap";
```

## Variants

- `modes` — Modes: `npx @lumioui/cli add action-swap-modes`
- `sort` — Sort: `npx @lumioui/cli add action-swap-sort`
- `styles` — Styles: `npx @lumioui/cli add action-swap-styles`
- `text-swap` — Text Swap: `npx @lumioui/cli add action-swap-text-swap`
- `view-modes` — View Modes: `npx @lumioui/cli add action-swap-view-modes`

## Props

### ActionSwapText

| Prop | Type | Notes |
| --- | --- | --- |
| `value` | `string` | Slot identity — when this changes, the text animates. |
| `children` | `ReactNode` | — |
| `mode?` | `ActionSwapMode` | Swap choreography. "cascade" needs a string child. Default "roll". |
| `animation?` | `LegacySwapAnimation` | @deprecated Use `mode`. "fade" maps to "blur". |
| `light?` | `boolean` | Cascade only: each letter of the incoming label switches on in place  in reading order (over 390ms). No band is drawn. Default false. |
| `lightColor?` | `string` | @deprecated No effect: no reading-light band is drawn any more. |
| `lightOnFill?` | `boolean` | @deprecated No effect: no reading-light band is drawn any more. |
| `className?` | `string` | Applied to the root View AND the swapped text (text classes are  inert on the View, layout classes are inert on the Text). |

### ActionSwapIcon

| Prop | Type | Notes |
| --- | --- | --- |
| `value` | `string` | Slot identity — when this changes, the icon animates. |
| `children` | `ReactNode` | — |
| `mode?` | `ActionSwapMode` | Swap choreography ("cascade" falls back to roll — icons are single  glyphs). Default "roll". |
| `animation?` | `LegacySwapAnimation` | @deprecated Use `mode`. |
| `className?` | `string` | — |

### ActionSwapButton

| Prop | Type | Notes |
| --- | --- | --- |
| `items` | `ActionSwapItem[]` | — |
| `value?` | `string` | Controlled active item id. |
| `defaultValue?` | `string` | Initial active item id (uncontrolled). Defaults to the first item. |
| `onValueChange?` | `(value: string, item: ActionSwapItem) => void` | — |
| `variant?` | `ActionSwapButtonVariant` | — |
| `size?` | `ActionSwapButtonSize` | — |
| `mode?` | `ActionSwapMode` | Swap choreography for icon + label slots. Default "roll". |
| `animation?` | `LegacySwapAnimation` | @deprecated Use `mode`. |
| `light?` | `boolean` | Cascade only: light the incoming label into place with a reading  light (see ActionSwapText). Default false. |
| `iconOnly?` | `boolean` | Hide the label — icon slot only. Defaults to size === "icon". |
| `cycle?` | `boolean` | Advance to the next item on press. Default true. |
| `disabled?` | `boolean` | — |
| `className?` | `string` | — |

### ActionSwap

| Prop | Type | Notes |
| --- | --- | --- |
| `states` | `ActionSwapState[]` | States to cycle through. Must have at least 2. |
| `value?` | `number` | Controlled active index. |
| `defaultValue?` | `number` | Initial active index (uncontrolled). Default 0. |
| `onStateChange?` | `(index: number) => void` | — |
| `variant?` | `"pill" | "plain" | "outline"` | Visual style. Default "pill". |
| `mode?` | `ActionSwapMode` | Swap choreography for icon + label. Default "roll". |
| `light?` | `boolean` | Cascade only: light the incoming label into place with a reading  light (see ActionSwapText). Default false. |
| `accessibilityLabelPrefix?` | `string` | Accessible label prefix. Default "Swap to". |
| `disabled?` | `boolean` | — |
| `className?` | `string` | — |

Source: https://lumioui.com/components/action-swap