輸入元件

NPS 淨推薦值調查卡

NPS 調查卡 React 元件:0–10 分段按鈕依貶損/被動/推薦者著色,選分後展開對應追問欄,送出切換感謝態,並附 npsCategory 與 npsScore 計算函式。

SaaS 常見的滿意度調查題型。0–10 十一顆分數按鈕依 NPS 慣例分成三個區間——0–6 貶損者(紅)、7–8 被動者(琥珀)、9–10 推薦者(綠)——選中後同區間整組淡染、選中那顆彈跳;下方展開依分數變化的追問輸入欄(低分問哪裡失望、高分問最喜歡哪一點),送出後整卡切換為打勾感謝態。另外匯出 npsCategory 與 npsScore 兩個純函式,讓你在後台用同一套規則把回收的分數換算成 NPS。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add nps-survey-card

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

編輯中的呼叫預設屬性
<NpsSurveyCard/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add https://webberui.com/r/nps-survey-card.json

或在 components.json 設定 registries 後,改用 @webberui/nps-survey-card 安裝。

使用

import { NpsSurveyCard, npsScore } from "@/components/ui/nps-survey-card";

<NpsSurveyCard
  onChange={(score) => console.log("選分", score)}
  onSubmit={({ score, comment }) => console.log(score, comment)}
  requireComment
/>

// 分數計算可單獨使用:推薦者% − 貶損者%,回傳 -100~100 的整數
npsScore([10, 9, 8, 6, 3]); // 40 − 40 = 0

Props

Prop型別預設值說明
valuenumber | null—受控選中分數(0–10);null 表示尚未選分,不提供此 prop 時為非受控模式
defaultValuenumber | nullnull非受控模式的初始分數
onChange(score: number) => void—選分時回呼(點擊、鍵盤方向鍵與數字鍵都會觸發)
onSubmit(result: { score: number; comment: string }) => void—按下送出時回呼,附分數與追問回覆(去除前後空白)
onReset() => void—提供時感謝態會顯示「再填一次」按鈕,按下後重置內部狀態並回呼
questionstring"你有多可能把我們推薦給朋友或同事?"主問題文字
followUpQuestionstring—追問文字模板,模板中的 {score} 會代入實際分數;提供時優先於 followUps 與內建預設
followUpsPartial<Record<NpsCategory, string>>—依類別覆寫追問文字(detractor/passive/promoter),同樣支援 {score} 佔位
showLabelsbooleantrue顯示兩端「完全不可能/非常可能」標籤
requireCommentbooleanfalse追問必填:留言為空時送出按鈕停用
compactbooleanfalse緊湊模式:縮小按鈕、字級與間距
labelsPartial<NpsSurveyCardLabels>—覆寫介面文案
classNamestring—透傳到最外層卡片

NpsSurveyCardLabels

欄位型別預設值說明
lowstring"完全不可能"0 分端的標籤文字
highstring"非常可能"10 分端的標籤文字
detractorstring"貶損者"0–6 分的類別名稱(無障礙播報用)
passivestring"被動者"7–8 分的類別名稱
promoterstring"推薦者"9–10 分的類別名稱
commentPlaceholderstring"想到什麼都可以寫"追問輸入框的 placeholder
commentRequiredstring"此欄為必填,寫幾個字就可以"requireComment 時顯示的必填提示
submitstring"送出"送出按鈕文字
thanksTitlestring"感謝你的回饋!"感謝態標題
thanksBodystring"我們會認真閱讀每一則意見。"感謝態說明文字
resetstring"再填一次"「再填一次」按鈕文字(需提供 onReset 才會顯示)

另外具名匯出 npsCategory(score)(把 0–10 分歸類為 "detractor" | "passive" | "promoter")、npsScore(scores)(推薦者百分比減貶損者百分比,四捨五入為整數;空陣列回傳 0)與 NpsCategory、NpsSurveyCardLabels 型別,方便在後台沿用同一套計分規則。

細節

  • 追問文字的決定順序:followUpQuestion(模板中 {score} 會代入實際分數)優先,其次 followUps 依類別覆寫,最後才是內建預設——低分問「我們哪裡讓你失望了?」、中分問「還差什麼就能讓你打更高分?」、高分問「最喜歡哪一點?」
  • 追問欄的 Enter 只會換行、不會送出,送出一律透過按鈕——避免打字到一半誤送
  • 窄容器時 11 顆按鈕以 flex-wrap 自動換行成兩排,不需要額外設定
  • 感謝態的「再填一次」只在提供 onReset 時顯示;受控模式下請在 onReset 回呼裡把 value 設回 null

可及性

  • 0–10 分數按鈕組為 role="radiogroup"(以主問題 aria-labelledby 命名),每顆分數為 role="radio" 搭配 aria-checked,並採 roving tabindex——Tab 進入群組後以 ←/→(或數字鍵、Home/End)移動選取
  • 選分後以 aria-live="polite" 區域播報分數與所屬類別(貶損者/被動者/推薦者),送出後播報感謝訊息
  • 追問輸入框以 label 關聯追問文字;requireComment 時同步設定 aria-required 並以 aria-describedby 連到必填提示
  • 使用者系統開啟「減少動態效果」時,停用選中彈跳、hover 抬升、展開與打勾動畫,狀態直接切換