your personal website on atproto - mirror blento.app
at button 51 lines 2.0 kB view raw
1<script lang="ts"> 2 import { cn } from '@foxui/core'; 3 4 let { rating, class: className }: { rating: number; class?: string } = $props(); 5 6 // Convert 0-10 rating to 0-5 stars 7 const starRating = $derived(Math.max(0, Math.min(10, rating ?? 0)) / 2); 8 const fullStars = $derived(Math.floor(starRating)); 9 const hasHalfStar = $derived(rating % 2 === 1); 10 const emptyStars = $derived(Math.max(0, 5 - fullStars - (hasHalfStar ? 1 : 0))); 11</script> 12 13{#snippet star(className: string)} 14 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="size-5 {className}"> 15 <path 16 fill="currentColor" 17 fill-rule="evenodd" 18 d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z" 19 clip-rule="evenodd" 20 /> 21 </svg> 22{/snippet} 23 24{#snippet halfStar()} 25 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-accent-500 size-5"> 26 <defs> 27 <linearGradient id="half-filled" x1="0%" y1="0%" x2="100%" y2="0%"> 28 <stop offset="50%" stop-color="currentColor" /> 29 <stop offset="50%" stop-color="var(--color-base-400)" /> 30 </linearGradient> 31 </defs> 32 <path 33 fill="url(#half-filled)" 34 fill-rule="evenodd" 35 d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z" 36 clip-rule="evenodd" 37 /> 38 </svg> 39{/snippet} 40 41<div class={cn('text-accent-500 flex', className)}> 42 {#each Array(fullStars)} 43 {@render star('text-accent-500')} 44 {/each} 45 {#if hasHalfStar} 46 {@render halfStar()} 47 {/if} 48 {#each Array(emptyStars)} 49 {@render star('text-base-400')} 50 {/each} 51</div>