---
title: Swipeout
description: Swipe a list row to reveal leading and trailing actions.
---
import Source from './_generated/swipeout.mdx';

Swipe a list row horizontally to reveal action buttons behind it. Dragging the content translates it to expose the trailing (and optional leading) action panel, then snaps open or closed on release with a momentum-feel transition. Only one row stays open at a time, and an outside tap or a scroll closes it — coordinated through a shared registry, like the overlay stack.

<DemoFrame component="swipeout" height={460} />

> **Info**
>
> Swipeout is a touch/pointer gesture — try it with a mouse drag on desktop, or on a touch device. The content layer keeps `touch-action: pan-y`, so vertical scrolling stays native while horizontal drags reveal the actions.

## Installation

```bash
npx touchcn add swipeout
```

## Usage

<CodeGroup>

```html Angular
<tcn-swipeout>
  <tcn-swipeout-actions side="trailing">
    <button tcnSwipeoutAction variant="destructive" (click)="remove()">Delete</button>
  </tcn-swipeout-actions>
  <div class="row">Meeting notes</div>
</tcn-swipeout>
```

```tsx React
import { TcnSwipeout, TcnSwipeoutAction } from '@/components/ui/swipeout';

<TcnSwipeout
  trailing={<TcnSwipeoutAction variant="destructive" onClick={remove}>Delete</TcnSwipeoutAction>}
>
  <div className="row">Meeting notes</div>
</TcnSwipeout>
```

```vue Vue
<script setup lang="ts">
import { TcnSwipeout, TcnSwipeoutAction } from '@/components/ui/swipeout';
</script>

<template>
  <TcnSwipeout>
    <template #trailing>
      <TcnSwipeoutAction variant="destructive" @click="remove">Delete</TcnSwipeoutAction>
    </template>
    <div class="row">Meeting notes</div>
  </TcnSwipeout>
</template>
```

</CodeGroup>

All gesture behaviour — pointer tracking, the `translateX` writes, snap thresholds, the single-open registry and outside/scroll dismissal — lives in the engine (`TcnSwipeoutDirective` / `useSwipeout`); the copied component owns only markup and the sliding content layer. iOS full-swipe-to-trigger-the-first-action is not implemented — a future engine addition can layer it on without changing this markup.

## Props

### Swipeout

| Prop                  | Type                                     | Default | Description                                          |
| --------------------- | ---------------------------------------- | ------- | --------------------------------------------------- |
| `disabled`            | `boolean`                                | `false` | Disable the gesture (an open row can still close).  |
| `leading` / `trailing` (React) | `ReactNode`                     | —       | Action buttons revealed on each side.               |
| `openedChange` / `onOpenChange` | `'leading' \| 'trailing' \| null` | —   | Fired when the open side changes.                   |

### Swipeout Action

| Prop      | Type                        | Default     | Description                          |
| --------- | --------------------------- | ----------- | ------------------------------------ |
| `variant` | `'default' \| 'destructive'`| `'default'` | Destructive tints the button red.    |

<Source />
