-
-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathprogress-with-value.tsx
59 lines (52 loc) · 2.11 KB
/
progress-with-value.tsx
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
'use client';
import * as React from 'react';
import * as ProgressPrimitive from '@radix-ui/react-progress';
import { cn } from '@/lib/utils';
interface ProgressWithValueProps
extends React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> {
position?: 'start' | 'start-outside' | 'follow' | 'end' | 'end-outside';
label?: (value?: number | null) => React.ReactNode;
valueClassName?: string;
}
const ProgressWithValue = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
ProgressWithValueProps
>(({ className, valueClassName, value, position = 'end', label, ...props }, ref) => {
const valueCommonClass = cn('absolute -top-0.5 left-0 h-fit px-4 w-full items-center hidden');
const ProgressValue = () => (
<span
className={cn(
'hidden',
position === 'start-outside' && 'block text-primary',
position === 'follow' && cn(valueCommonClass, 'flex justify-end text-primary-foreground'),
position === 'start' && cn(valueCommonClass, 'flex justify-start text-primary-foreground'),
position === 'end' && cn(valueCommonClass, 'flex justify-end text-primary'),
position === 'end-outside' && 'block text-primary',
valueClassName,
)}
>
{typeof label === 'function' ? label(value) : `${value}%`}
</span>
);
return (
<div className="flex items-center gap-2">
{position === 'start-outside' && <ProgressValue />}
<ProgressPrimitive.Root
ref={ref}
className={cn('relative h-5 w-full overflow-hidden rounded-full bg-secondary', className)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
>
{position === 'follow' && <ProgressValue />}
</ProgressPrimitive.Indicator>
{(position === 'start' || position === 'end') && <ProgressValue />}
</ProgressPrimitive.Root>
{position === 'end-outside' && <ProgressValue />}
</div>
);
});
ProgressWithValue.displayName = 'ProgressWithValue';
export { ProgressWithValue };