Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x 2x 4x 2x 2x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 2x 2x 2x 2x 4x 6x 6x | import * as Slider from '@radix-ui/react-slider';
// Utils
import { combineClasses } from '@shared/utils';
import { pluralize } from '@/utils';
// Components
import { VoteMetric } from './VoteMetric';
interface VoteProgressBarProps {
likes: number;
dislikes: number;
}
export const VoteProgressBar = ({ likes, dislikes }: VoteProgressBarProps) => {
const total = likes + dislikes;
const hasLikes = likes > 0;
const hasDislikes = dislikes > 0;
const isEmptyVote = !hasLikes && !hasDislikes;
const hasBothVotes = hasLikes && hasDislikes;
const isLikeOnly = hasLikes && !hasDislikes;
const isDislikeOnly = hasDislikes && !hasLikes;
// Single-sided vote → fill the bar to 100%
const percent = isEmptyVote
? 0
: hasBothVotes
? Math.round((likes / total) * 100)
: 100;
const rangeColorClass = isDislikeOnly ? 'bg-gray-300' : 'bg-pink-600';
const rangeRadiusClass =
isLikeOnly || isDislikeOnly ? 'rounded-xs' : 'rounded-l-xs';
return (
<div className="w-full">
<div className="mb-2 flex items-center justify-between text-slate-700">
<VoteMetric
label={pluralize(likes, 'Like')}
value={likes}
className="items-start text-pink-300"
/>
<VoteMetric
label={pluralize(dislikes, 'Dislike')}
value={dislikes}
className="items-end text-gray-300"
/>
</div>
{!isEmptyVote && (
<Slider.Root
className="relative flex h-2 w-full touch-none select-none items-center"
value={[percent]}
max={100}
step={1}
disabled
>
<Slider.Track className="relative h-2 w-full grow rounded-xs bg-gray-300">
<Slider.Range
className={combineClasses(
'absolute h-full',
rangeRadiusClass,
rangeColorClass,
)}
/>
</Slider.Track>
{hasBothVotes && (
<Slider.Thumb
className="block h-2 w-1 bg-white shadow focus:outline-none"
aria-hidden
/>
)}
</Slider.Root>
)}
</div>
);
};
|