flutter_swipe_to_reply

A lightweight Flutter widget that adds a familiar swipe-to-reply gesture to any child. It works well for chat bubbles, message rows, comments, files, and other horizontal reply interactions.

The package handles the gesture, movement, indicator, and haptic feedback. Your app decides what replying means.

Features

  • Swipe any widget left or right.
  • Trigger a callback after a configurable distance.
  • Theme-aware default reply indicator using Icons.reply.
  • Configurable indicator icon as a Widget.
  • Optional custom indicator builder.
  • Optional haptic feedback when the gesture crosses the trigger threshold.
  • Haptic rearming after returning to the origin during the same drag.
  • Release-based confirmation: crossing the threshold never invokes the action before the pointer is released.
  • No app-specific dependencies.

Installation

dependencies:
  flutter_swipe_to_reply: ^0.2.0

Then import the package:

import 'package:flutter_swipe_to_reply/flutter_swipe_to_reply.dart';

Basic usage

SwipeToReply(
  direction: SwipeToReplyDirection.right,
  onReply: () {
    // Select the item as the reply target.
  },
  child: messageBubble,
)

Outgoing and incoming messages

For chat UIs, outgoing messages usually swipe left and incoming messages swipe right.

SwipeToReply(
  direction: isMine
      ? SwipeToReplyDirection.left
      : SwipeToReplyDirection.right,
  onReply: () => setReplyTarget(message),
  child: messageBubble,
)

Custom indicator

Use indicatorIcon when you only need to replace the icon.

SwipeToReply(
  indicatorIcon: const Icon(Icons.reply_all),
  onReply: () {},
  child: child,
)

Use indicatorBuilder when you want to provide your own animation, color, size, or layout.

SwipeToReply(
  direction: SwipeToReplyDirection.left,
  indicatorBuilder: (context, progress, direction) {
    return Opacity(
      opacity: progress,
      child: const Icon(Icons.reply),
    );
  },
  onReply: () {},
  child: child,
)

Tuning the gesture

SwipeToReply(
  triggerDistance: 56,
  maxDragDistance: 84,
  hapticRearmDistance: 0,
  resetDuration: const Duration(milliseconds: 180),
  resetCurve: Curves.easeOutCubic,
  enableHapticFeedback: true,
  onReply: () {},
  child: child,
)

triggerDistance is the point at which the gesture becomes eligible. The callback still runs only if the pointer is released while the drag remains at or beyond that distance.

Haptic rearming

Haptic feedback fires once when the active drag first reaches triggerDistance. If the pointer returns to hapticRearmDistance, feedback is armed again and a later threshold crossing produces another pulse without ending the gesture.

The default hapticRearmDistance is 0, so the user must return completely to the starting point. A small positive value can provide additional tolerance:

SwipeToReply(
  triggerDistance: 56,
  hapticRearmDistance: 8,
  onReply: selectReplyTarget,
  child: messageBubble,
)

The rearm distance must be non-negative and smaller than triggerDistance. Moving slightly below the trigger threshold does not rearm feedback, which prevents repeated pulses caused by small pointer movements.

Configuration

Property Default Purpose
direction right Allowed horizontal swipe direction.
enabled true Enables or disables gesture recognition.
triggerDistance 54 Distance required before release can reply.
maxDragDistance 78 Maximum visual displacement.
enableHapticFeedback true Emits a light pulse on armed crossings.
hapticRearmDistance 0 Distance that rearms haptic feedback.
resetDuration 170ms Return animation duration.
resetCurve easeOutCubic Return animation curve.
indicatorIcon Icons.reply Widget used by the default indicator.
indicatorBuilder null Replaces the complete indicator.

Example

The repository includes a runnable conversation that demonstrates incoming and outgoing directions, reply selection, a composer, and repeated haptic threshold crossings:

cd example
flutter run

Notes

This package does not mutate messages, send network requests, or manage reply state. Keep those side effects in your app and use onReply to connect the gesture to your own flow.

Libraries

flutter_swipe_to_reply
Horizontal swipe-to-reply interactions for Flutter widgets.