Downgrade impact

Pro

What moving to a smaller plan takes away, before you confirm: the features you lose (and what happens to anything that used them), the new monthly total, and when it takes effect. Confirm stays locked until you acknowledge the losses.

Markdown

Preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/downgrade-impact

Brings in: button, locale, locked, ops, utils · npm: lucide-react@^1.67.0

Usage

TSX · The example above
"use client"

import { DowngradeImpact } from "@/components/downgrade-impact"
import type { PlanTier } from "@/lib/ops"

const enterprise: PlanTier = { id: "enterprise", name: "Enterprise", perSeat: 499, tagline: "Everything in Team, plus people behind it", includes: ["Everything in Team", "Security and deployment controls", "A named engineer on your account"] }
const team: PlanTier = { id: "team", name: "Team", perSeat: 249, tagline: "The whole product for an in-house team", includes: ["Chat, agents and reports", "Approvals and audit log", "SSO sign-in"] }

export default function Example() {
  return (
    <DowngradeImpact
      className="max-w-xl"
      from={enterprise}
      to={team}
      seats={8}
      losses={[
        { feature: "Deployment controls", consequence: "Your two Production deploy windows are removed; deploys follow the default approval rules." },
        { feature: "A named engineer", consequence: "Support moves to the shared queue." },
      ]}
      effectiveAt="2026-12-01"
      onConfirm={() => {}}
      onCancel={() => {}}
    />
  )
}

<DowngradeImpact>

PropTypeDefaultDescription
fromrequiredPlanTier—The current plan.
torequiredPlanTier—The smaller plan being moved to.
seatsrequirednumber—Seats on the account, for the old and new monthly totals.
lossesrequired{ feature: string; consequence: string }[]—What goes, and what happens to things that depended on it.
effectiveAtrequiredstring—When the new plan takes effect, as an ISO date.
onConfirmrequired() => void—Called on confirm, which stays locked until the losses are acknowledged.
onCancel(() => void) | undefined—Shows a button to keep the current plan; called when it's clicked.
classNamestring | undefined—Extra classes for the outer element.

Strings

The fixed words, in English by default. Change any of them under downgradeImpact in <LocaleProvider strings={{ … }}>; the table is exported as downgradeImpactStrings.

KeyEnglish
moveToMove to {plan}
toto
price${amount}
perMontha month
youllLoseYou’ll lose
takesEffectTakes effect on {date}. Until then nothing changes.
understandI understand what {plan} doesn’t include.
keepKeep {plan}
tickFirstTick the box first.