KQ-1757 · PROMOTER/SCALE

Promoter Scale

A score survey: zero to ten, then the one question written for the band the answer falls in. Picking a score fills the segments from zero up to it in a quick wave — each fill sweeping in on springs.snap a few milliseconds after the last, every one in the picked band's colour, draining from the top when the score drops — and a beat later the scale shrinks into a summary chip, its segments travelling on springs.glide into the chip's mini ticks while the follow-up slides in from 16px. The scale is a real radio group: arrows and Home or End move the score with the wave following, number keys pick one (1 then 0 is ten) and Enter, Space or a click confirms; the chip brings the scale back, Escape in the follow-up does too, and sending, thanked, failed and dismissed states are covered with the card's measured height gliding between them.

KQ-1757 · PROMOTER/SCALE

Order FW-2041 · three ferns, arrived Tuesday

Arrow keys or a number choose a score; 1 then 0 is ten. Enter confirms it.

How likely are you to recommend Fernworks to a friend or colleague?

0 · Not likelyVery likely · 10

pick a score · fernworks survey

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/promoter-scale

Props

segmentStyle
"tiles" | "bars" | "dots"
default "tiles"
How the scale is drawn: equal tiles that fill from the left, bars rising left to right that fill from the base, or discs that fill from the centre.
bandPalette
"status" | "tonal" | "quiet"
default "status"
Band colours as pigment: danger, warn and success; the accent at three depths; or quiet greys with promoters in the accent.
cornerRadius
number
default 8
Corner radius in px of the segments, ticks, chip, field and buttons; the card rounds with it.
question
string
default "How likely are you to recommend Fernworks to a friend or colleague?"
The question over the scale; it also names the radio group.
bands
PromoterBand[]
default defaultPromoterBands
Score bands low to high as { id, label, from, to, colour? }: Detractor 0–6, Passive 7–8, Promoter 9–10 by default.
followUps
Record<string, PromoterFollowUp>
default defaultPromoterFollowUps
The follow-up for each band id as { question, placeholder?, chips? }; chips become quick reason toggles.
value / defaultValue
number | null
default — / null
The score.
onValueChange
(score) => void
default —
Fires as a click, an arrow or a number key changes the score.
onScore
(score, band) => void
default —
A score was confirmed and its follow-up opened.
onSubmit
(answer) => void | Promise
default —
Send or Skip was pressed with { score, band, comment, reasons }. Return a promise to show sending; a rejection shows the failed state with the answer kept.
onDismiss
() => void
default —
The survey was dismissed; it folds to one line with Undo.
lowLabel
string
default "Not likely"
Words under the low end of the scale.
highLabel
string
default "Very likely"
Words under the high end of the scale.
max
number
default 10
The top of the scale.
sendState
"idle" | "sending" | "sent" | "failed"
default —
Controlled send state, for a host that tracks delivery itself; by default it follows the promise onSubmit returns.
disabled
boolean
default false
The survey can be read but not answered.
className
string
default —
Classes for the survey's outer box.