caliper uidocs

Swipe actions

Free

Row actions revealed by swiping, with a keyboard route to the same actions.

Installs components/ui/swipe-actions.tsxDepends on none beyond ReactMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/swipe-actions.json
Atlas platformUpdated 2 hours ago

Swipe the row, or open its actions with the keyboard.

When to use #

Use it for

  • List rows on touch screens where Archive and Delete should stay out of the way until needed.
  • Inbox, task and project lists with a small set of row-level actions.

Skip it when

  • The row needs more than three actions; open a menu instead.
  • The action is irreversible and unconfirmed; pair it with an undo.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/swipe-actions.json

Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above.

example.tsx
import { useState } from "react"
import { SwipeActions } from "@/components/ui/swipe-actions"

export function ProjectRow() {
  const [status, setStatus] = useState("Swipe the row, or open its actions with the keyboard.");
  return (
    <div className="grid w-full max-w-sm gap-3">
      <SwipeActions
        label="Atlas platform"
        actions={[
          { label: "Archive", onSelect: () => setStatus("Atlas archived.") },
          { label: "Delete", tone: "destructive", onSelect: () => setStatus("Atlas deleted.") },
        ]}
      >
        <span className="grid px-4 py-3 text-sm">
          <span className="font-medium">Atlas platform</span>
          <span className="text-muted-foreground">Updated 2 hours ago</span>
        </span>
      </SwipeActions>
      <p role="status" className="text-sm text-muted-foreground">{status}</p>
    </div>
  );
}

API reference #

SwipeActions

component
PropTypeDefault
label *string—
children *ReactNode—
actions *readonly SwipeAction[]—
classNamestring—

Accessibility #

It is built on native elements and keeps aria-expanded and aria-label in step with state.

No custom key handling; Tab and the native activation keys do the work.

Motion #

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.