Cancellation Flow
A multi-step subscription cancellation modal with reason capture, retention offers, and a final confirmation step.
Preview
Features
- Three-step flow: reason, retention offers, confirmation
- Built-in defaults for reasons and retention options
- Async hooks for retention actions and cancellation
- Optional feedback field for churn analysis
- Simple API with overrideable copy and offers
Install Summary
This kit will add the following files and dependencies to your project. Download the bundle and extract it into your project root.
Component Files
| File | Path |
|---|---|
| cancellation-flow.tsx | components/billing/cancellation-flow/cancellation-flow.tsx |
| types.ts | components/billing/cancellation-flow/types.ts |
| index.ts | components/billing/cancellation-flow/index.ts |
Dependencies
Install these dependencies before using the component:
Terminal
bash
npx shadcn@latest add badge button dialog label select textareaTerminal
bash
npm install @phosphor-icons/reactInstallation
Download the complete bundle as a ZIP file, or copy the text bundle to your clipboard:
Component Files
The component consists of the following files:
1. cancellation-flow.tsx
cancellation-flow.tsx
tsx
"use client";
import { useEffect, useMemo, useState } from "react";
import {
ArrowDownRight,2. types.ts
types.ts
tsx
import type { ElementType } from "react";
export type CancellationStep = "reason" | "retention" | "confirm";
export interface CancellationReason {3. index.ts
index.ts
tsx
export { CancellationFlow } from "./cancellation-flow";
export type * from "./types";
Usage
app/billing/page.tsx
tsx
"use client";
import { useState } from "react";
import { CancellationFlow } from "@/components/billing/cancellation-flow";
Props
| Prop | Type | Default |
|---|---|---|
| open | boolean | Required |
| onOpenChange | (open) => void | Required |
| planName | string | "Pro" |
| reasons | CancellationReason[] | Defaults provided |
| offers | RetentionOffer[] | Defaults provided |
| showRetentionStep | boolean | true |
| onSelectOffer | (offer) => void | - |
| onConfirmCancellation | (payload) => void | - |
| className | string | - |