star-rating-fractions
stackzero/star-rating-fractionsFreeComponent
stackzero publishes no description for this item.
Install it
npx shadcn@latest add https://ui.stackzero.co/r/star-rating-fractions.jsonSource
1"use client";23import { cn } from "@/lib/utils";4import { Star } from "lucide-react";5import * as React from "react";67// Add ID generator outside component to maintain counter8let nextId = 0;9const generateStarIds = (count: number) =>10 Array.from({ length: count }, () => `star-${nextId++}`);1112interface StarRatingBasicProps {13 value: number;14 onChange?: (value: number) => void;15 className?: string;16 iconSize?: number;17 maxStars?: number;18 readOnly?: boolean;19 color?: string;20}2122const StarIcon = React.memo(23 ({24 iconSize,25 index,26 isInteractive,27 onClick,28 onMouseMove,29 style,30 }: {31 index: number;32 style: React.CSSProperties;33 iconSize: number;34 onClick: (e: React.MouseEvent<SVGElement>) => void;35 onMouseMove: (e: React.MouseEvent<SVGElement>) => void;36 isInteractive: boolean;37 }) => (38 <Star39 key={index}40 size={iconSize}41 fill={style.fill}42 color={style.color}43 onClick={onClick}44 onMouseMove={onMouseMove}45 className={cn(46 "transition-colors duration-200",47 isInteractive && "cursor-pointer"48 )}49 style={style}50 />51 )52);53StarIcon.displayName = "StarIcon";5455const StarRating_Fractions = ({56 className,57 color = "#e4c616",58 iconSize = 24,59 maxStars = 5,60 onChange,61 readOnly = false,62 value,63}: StarRatingBasicProps) => {64 const [hoverRating, setHoverRating] = React.useState<number | null>(null);65 // Generate stable IDs on component mount66 const [starIds] = React.useState(() => generateStarIds(maxStars));6768 const calculateRating = React.useCallback(69 (index: number, event: React.MouseEvent<SVGElement>) => {70 const star = event.currentTarget;71 const rect = star.getBoundingClientRect();72 const x = event.clientX - rect.left;73 const width = rect.width;74 const clickPosition = x / width;7576 let fraction = 1;77 if (clickPosition <= 0.25) fraction = 0.25;78 else if (clickPosition <= 0.5) fraction = 0.5;79 else if (clickPosition <= 0.75) fraction = 0.75;8081 return index + fraction;82 },83 []84 );8586 const handleStarClick = React.useCallback(87 (index: number, event: React.MouseEvent<SVGElement>) => {88 if (readOnly || !onChange) return;89 const newRating = calculateRating(index, event);90 onChange(newRating);91 },92 [readOnly, onChange, calculateRating]93 );9495 const handleStarHover = React.useCallback(96 (index: number, event: React.MouseEvent<SVGElement>) => {97// … truncated
What it pulls in
npm packages
Files it writes
More from stackzero
All 112 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| face-rating-basicface-rating-basic | stackzero | Components | Free | 1 dep | |
| face-rating-gradientface-rating-gradient | stackzero | Components | Free | 2 deps | |
| image-carousel-basicimage-carousel-basic | stackzero | Components | Free | 5 deps | |
| image-viewer-basicimage-viewer-basic | stackzero | Components | Free | 3 deps | |
| image-viewer-basic-ex-01image-viewer-basic-ex-01 | stackzero | Components | Free | 1 dep | |
| image-viewer-basic-ex-02image-viewer-basic-ex-02 | stackzero | Components | Free | 1 dep | |
| image-viewer-motionimage-viewer-motion | stackzero | Components | Free | 4 deps | |
| image-viewer-motion-ex-01image-viewer-motion-ex-01 | stackzero | Components | Free | 1 dep |
