Experimental Badge

A badge that opens the concrete risks of a beta feature and a one-tap way back to the stable version, so people don't trust it blindly.

StopsTrusted a beta feature and lost work

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/experimental-badge.json

The files land in your project. They're yours to edit.

Usage

experimental-badge-usage.tsx
import { ExperimentalBadge } from "@/components/ui/experimental-badge"

<ExperimentalBadge
  feature="Smart inbox"
  defaultOpen
  risks={[
    {
      kind: "data",
      text: "Auto-sorted folders may be reset while we tune the model. Your emails are never deleted.",
    },
    { kind: "change", text: "Which emails count as “Important” will change week to week." },
  ]}
  feedbackHref="#feedback"
  switchBackNote="Your folders stay here for when you come back."
  onSwitchBack={() => new Promise<void>((resolve) => setTimeout(() => (setSmart(false), resolve()), 700))}
/>

What it catches

  • Unclear risk of using an unfinished feature
  • No way back, by offering a switch to stable
  • What happens to work when switching back

Props

ExperimentalBadge props
PropTypeDefault
feature* (required)

The feature's name, e.g. "Smart inbox".

string—
stage

How unfinished the feature is.

ExperimentStage"beta"
risks

What can go wrong, as concrete sentences. Defaults depend on `stage`.

ExperimentRisk[]DEFAULT_RISKS[stage]
feedbackHref

Where feedback goes: a form, an issue, a mailto.

string—
onFeedback

Or handle feedback yourself (open your widget).

() => void—
onSwitchBack

Turn the feature off and go back to the stable version. May return a promise.

() => void | Promise<void>—
switchBackNote

What happens to their work when they switch back, e.g. "Your 3 saved views stay here for when you return."

string—
open

Controlled open state of the panel.

boolean—
defaultOpen

Initial open state when uncontrolled.

booleanfalse
onOpenChange

Called when the panel opens or closes.

(open: boolean) => void—
label

Badge text. Defaults to the stage name.

stringstageLabels[stage]
heading

Panel heading; `{feature}` and `{stage}` are filled in.

string"{feature} is in {stage}"
feedbackLabel

Text for the feedback link.

string"Send feedback"
switchBackLabel

Text for the switch-back button.

string"Use stable version"
switchingLabel

Button text while switching back.

string"Switching…"
errorText

Shown when switching back fails.

string"Couldn’t switch back. Try again."

* required. Also accepts the native props of <span> (className, aria-*, data-*…), passed through to it.

Accessibility

  • The badge is a button with aria-expanded and a descriptive aria-label
  • The panel is role="dialog" with an aria-label
  • Switch-back errors use role="alert"

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Lists the risks you write; it can't know them
  • Switching back runs your onSwitchBack

What it stops

Trusted a beta feature and lost work

Also known as

beta · experimental · labs · preview · feature flag · early access · badge · opt out

Dependencies

Pairs well with