56 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { IconStar, IconStarFilled } from "@components/icons.tsx";
 | |
| import { useSignal } from "@preact/signals";
 | |
| import { useState } from "preact/hooks";
 | |
| 
 | |
| export const SmallRating = (
 | |
|   { max = 5, rating }: { max?: number; rating: number },
 | |
| ) => {
 | |
|   return (
 | |
|     <div
 | |
|       class="flex gap-1 rounded"
 | |
|       style={{ filter: "drop-shadow(0px 3px 3px black)" }}
 | |
|     >
 | |
|       {Array.from({ length: max }).map((_, i) => {
 | |
|         return (
 | |
|           <span>
 | |
|             {(i + 1) <= rating
 | |
|               ? <IconStarFilled class="w-3 h-3" />
 | |
|               : <IconStar class="w-3 h-3" />}
 | |
|           </span>
 | |
|         );
 | |
|       })}
 | |
|     </div>
 | |
|   );
 | |
| };
 | |
| 
 | |
| export const Rating = (
 | |
|   props: { max?: number; rating: number },
 | |
| ) => {
 | |
|   const [rating, setRating] = useState(props.rating);
 | |
|   const [hover, setHover] = useState(0);
 | |
|   const max = useSignal(props.max || 5);
 | |
| 
 | |
|   return (
 | |
|     <div
 | |
|       class="flex items-center gap-2 px-5 rounded-2xl bg-gray-200 z-10"
 | |
|       style={{ color: "var(--foreground)", background: "var(--background)" }}
 | |
|     >
 | |
|       {Array.from({ length: max.value }).map((_, i) => {
 | |
|         return (
 | |
|           <span
 | |
|             class={`cursor-pointer opacity-${
 | |
|               (i + 1) <= rating ? 100 : (i + 1) <= hover ? 20 : 100
 | |
|             }`}
 | |
|             onMouseOver={() => setHover(i + 1)}
 | |
|             onClick={() => setRating(i + 1)}
 | |
|           >
 | |
|             {(i + 1) <= rating || (i + 1) <= hover
 | |
|               ? <IconStarFilled class="w-4 h-4" />
 | |
|               : <IconStar class="w-4 h-4" />}
 | |
|           </span>
 | |
|         );
 | |
|       })}
 | |
|     </div>
 | |
|   );
 | |
| };
 |