Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Promotion Banner Billing Block for Radix UI

A 30 percent off banner with a copyable code and the days left, whose sentence and button follow the plan chosen in a select, with a dismiss that leaves an Undo.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Offer a promotion that checks itself against the customer's plan, with this promotion banner for React with Radix UI. It opens with the account of Thistlebox, a recipe organiser. A hairline frame with a plus mark on each corner starts with a tinted banner: a Badge for 30 percent off for 6 months, "Ends 31 Oct, 16 days left" worked out from a fixed date, the code SUMMER30 with a Copy Button that copies it for real, a sentence, and the one Shine Button. Under it a Native Select says which plan you are on, and the banner follows it. On Free the offer applies when you upgrade and the button shows the Pro plans; on Pro monthly the button applies it to the next invoice and the sentence prices the saving; on Pro yearly the offer is not valid and the button waits. Applied, it reads "SUMMER30 applied: 30 percent off from 12 Nov to 12 Apr". A dismiss button removes the banner and leaves a line with Undo. It's built from Badge, Copy Button, Native Select, Button, Shine Button and Guides, with a CSS entrance only. For billing settings, account pages and any app that runs promotions.

FAQ

How do I change the offer?

The offer is at the top of the file: CODE, PERCENT, MONTHS, the Pro price in PRO_CENTS, and the dates AS_OF, ENDS, FROM and UNTIL. The days left, the saving a month and the saving in all are worked out from them, so only the dates and the numbers need to change. The plan choices are PLAN_CHOICES; in your app read the customer's real plan and the offer from your billing provider.

What does the banner do for each plan?

It has four states, derived from the plan and whether the code was applied: upgrade (Free), ready (Pro monthly), applied, and blocked (Pro yearly). Each has its own sentence and button label, and changing the plan clears an applied code. The button on Free is a preview here: it moves the select to Pro monthly so you can see the offer as that customer would. In your app it links to your plans page.

Does the code really copy?

Yes, the Copy button writes SUMMER30 to the clipboard and says "Code copied" to a screen reader. Browsers only allow it on a secure page (https or localhost); where the clipboard is refused it says it could not copy.

What does applying do, and what stays local?

It marks the code applied in the page and says "SUMMER30 applied in this demo. Nothing was charged." in a polite status message. No invoice changes. In your app send the code and the subscription to your server, let your billing provider validate it, and show the discount it returns. Dismissing is also local and does not remember anything after a reload.

Is it accessible?

The banner's state is written in its sentence, never only in the button's look, and a button that waits stays focusable and answers when pressed. Dismiss and Undo are named buttons: after either, focus moves to the other so a keyboard user never loses their place. The days left and the dates are text in time elements.