Feedback widget
BlockA small widget to rate and comment from any page.
pnpm dlx shadcn@latest add https://caliperui.site/r/feedback-widget.jsonWhen to use #
Use it for
- Collecting quick product feedback.
Skip it when
- You need a full survey.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/feedback-widget.json
Adds its 6 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { useState } from "react" import { FeedbackWidget } from "@/components/ui/feedback-widget" const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export function FeedbackWidgetDemo() { const [scale] = useState<"thumbs" | "faces">("thumbs"); return ( <FeedbackWidget key={scale} scale={scale} className="max-w-xl" onSubmit={async ({ comment }) => { await wait(700); if (/fail/i.test(comment)) return { error: "We couldn't send that. Try again." }; }} /> ); }
API reference #
FeedbackWidget
component
PropTypeDefault
questionstring"Was this page helpful?"
scale"thumbs" | "faces""thumbs"
onSubmit *(feedback: { rating: FeedbackRating; comment: string; }) => FeedbackResult | Promise<FeedbackResult>—
thanksstring"Thanks, that helps us improve."
classNamestring—
Accessibility #
It exposes status and radiogroup semantics, with aria-hidden, aria-label and aria-labelledby kept in step with state. Changes that matter are announced through a live region.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.