Vote Feedback
feedback-ui/vote-feedbackFreeComponent
A feedback component with upvote/downvote functionality
Install it
npx shadcn@latest add https://feedback-ui.kelet.ai/r/vote-feedback.jsonSource
1import * as React from "react"2import { VoteFeedback, type VoteFeedbackRootProps } from "@kelet-ai/feedback-ui"3import { ThumbsDown, ThumbsUp } from "lucide-react"45import { cn } from "@/lib/utils"6import { Button } from "@/components/ui/button"7import {8 Popover,9 PopoverContent,10 PopoverTrigger,11} from "@/components/ui/popover"12import { Textarea } from "@/components/ui/textarea"1314interface ShadcnVoteFeedbackProps15 extends Omit<VoteFeedbackRootProps, "children"> {16 children?: React.ReactNode17 variant?: "default" | "outline" | "ghost" | "secondary"18 size?: "default" | "sm" | "lg" | "icon"19 title?: string20 description?: string21 placeholder?: string22 className?: string23}2425const ShadcnVoteFeedback = React.forwardRef<26 HTMLDivElement,27 ShadcnVoteFeedbackProps28>(29 (30 {31 children,32 variant = "outline",33 size = "sm",34 title = "Feedback",35 description = "Help us improve by sharing your thoughts.",36 placeholder = "What could we do better?",37 className,38 ...props39 },40 ref41 ) => {42 let selectedVariant = variant43 let selectedBg = ""44 switch (variant) {45 case "outline":46 selectedBg = "bg-secondary"47 break48 case "secondary":49 selectedVariant = "default"50 break51 case "ghost":52 selectedBg = "bg-secondary"53 break54 case "default":55 selectedVariant = "secondary"56 break57 }58 return (59 <div ref={ref} className={cn("flex items-center gap-1", className)}>60 <VoteFeedback.Root {...props}>61 {/* Upvote Button */}62 <VoteFeedback.UpvoteButton asChild>63 {({ isSelected }) => (64 <Button65 variant={isSelected ? selectedVariant : variant}66 size={size}67 className={`h-8 w-8 p-0 ${isSelected ? `${selectedBg}` : ""}`}68 data-selected={isSelected}69 aria-label="Helpful"70 >71 <ThumbsUp className="h-4 w-4" />72 <span className="sr-only">Helpful</span>73 </Button>74 )}75 </VoteFeedback.UpvoteButton>7677 {/* Downvote Button with Popover */}78 <Popover>79 <VoteFeedback.DownvoteButton asChild>80 {({ isSelected }) => (81 <PopoverTrigger asChild>82 <Button83 variant={isSelected ? selectedVariant : variant}84 size={size}85// … truncated
What it pulls in
npm packages
Other registry items
