@@ -8,7 +8,7 @@ import { cn } from "@/lib/utils"
88
99const SEGMENT_COUNT = 5
1010
11- const progressVariants = cva ( "flex flex-wrap items-center gap-2.5" , {
11+ const progressVariants = cva ( "group/progress flex flex-wrap items-center gap-2.5" , {
1212 variants : {
1313 size : {
1414 sm : "" ,
@@ -32,25 +32,6 @@ const progressVariants = cva("flex flex-wrap items-center gap-2.5", {
3232 } ,
3333} )
3434
35- type ProgressContextValue = Required < VariantProps < typeof progressVariants > > & {
36- value : number | null
37- min : number
38- max : number
39- }
40-
41- const ProgressContext = React . createContext < ProgressContextValue > ( {
42- size : "default" ,
43- edge : "round-edge" ,
44- type : "default" ,
45- value : null ,
46- min : 0 ,
47- max : 100 ,
48- } )
49-
50- function useProgress ( ) {
51- return React . useContext ( ProgressContext )
52- }
53-
5435function Progress ( {
5536 className,
5637 children,
@@ -62,92 +43,64 @@ function Progress({
6243 max,
6344 ...props
6445} : ProgressPrimitive . Root . Props & VariantProps < typeof progressVariants > ) {
65- const context = React . useMemo (
66- ( ) => ( {
67- size : size ?? "default" ,
68- edge : edge ?? "round-edge" ,
69- type : type ?? "default" ,
70- value : value ?? null ,
71- min : min ?? 0 ,
72- max : max ?? 100 ,
73- } ) ,
74- [ size , edge , type , value , min , max ]
75- )
7646 return (
77- < ProgressContext . Provider value = { context } >
78- < ProgressPrimitive . Root
79- value = { value }
80- min = { min }
81- max = { max }
82- data-slot = "progress"
83- data-size = { context . size }
84- data-edge = { context . edge }
85- data-type = { context . type }
86- className = { cn ( progressVariants ( { size, edge, type } ) , className ) }
87- { ...props }
88- >
89- { children }
90- { type === "segmented" ? (
91- < ProgressSegments />
92- ) : (
93- < ProgressTrack >
94- < ProgressIndicator />
95- </ ProgressTrack >
96- ) }
97- </ ProgressPrimitive . Root >
98- </ ProgressContext . Provider >
47+ < ProgressPrimitive . Root
48+ value = { value }
49+ min = { min }
50+ max = { max }
51+ data-slot = "progress"
52+ data-size = { size }
53+ data-edge = { edge }
54+ data-type = { type }
55+ className = { cn ( progressVariants ( { size, edge, type } ) , className ) }
56+ { ...props }
57+ >
58+ { children }
59+ { type === "segmented" ? (
60+ < ProgressSegments
61+ value = { value ?? null }
62+ min = { min ?? 0 }
63+ max = { max ?? 100 }
64+ />
65+ ) : (
66+ < ProgressTrack >
67+ < ProgressIndicator />
68+ </ ProgressTrack >
69+ ) }
70+ </ ProgressPrimitive . Root >
9971 )
10072}
10173
102- const trackVariants = cva (
103- "relative flex w-full items-center overflow-x-hidden rounded-full bg-secondary" ,
104- {
105- variants : {
106- size : {
107- sm : "h-0.5" ,
108- default : "h-1" ,
109- lg : "h-2" ,
110- xl : "h-3" ,
111- } ,
112- } ,
113- defaultVariants : {
114- size : "default" ,
115- } ,
116- }
117- )
118-
11974function ProgressTrack ( { className, ...props } : ProgressPrimitive . Track . Props ) {
120- const { size } = useProgress ( )
12175 return (
12276 < ProgressPrimitive . Track
12377 data-slot = "progress-track"
124- className = { cn ( trackVariants ( { size } ) , className ) }
78+ className = { cn (
79+ "relative flex w-full items-center overflow-x-hidden rounded-full bg-secondary" ,
80+ "group-data-[size=sm]/progress:h-0.5" ,
81+ "group-data-[size=default]/progress:h-1" ,
82+ "group-data-[size=lg]/progress:h-2" ,
83+ "group-data-[size=xl]/progress:h-3" ,
84+ className
85+ ) }
12586 { ...props }
12687 />
12788 )
12889}
12990
130- const indicatorVariants = cva ( "h-full bg-primary transition-all" , {
131- variants : {
132- edge : {
133- "round-edge" : "rounded-full" ,
134- "square-edge" : "rounded-none" ,
135- } ,
136- } ,
137- defaultVariants : {
138- edge : "round-edge" ,
139- } ,
140- } )
141-
14291function ProgressIndicator ( {
14392 className,
14493 ...props
14594} : ProgressPrimitive . Indicator . Props ) {
146- const { edge } = useProgress ( )
14795 return (
14896 < ProgressPrimitive . Indicator
14997 data-slot = "progress-indicator"
150- className = { cn ( indicatorVariants ( { edge } ) , className ) }
98+ className = { cn (
99+ "h-full bg-primary transition-all" ,
100+ "group-data-[edge=round-edge]/progress:rounded-full" ,
101+ "group-data-[edge=square-edge]/progress:rounded-none" ,
102+ className
103+ ) }
151104 { ...props }
152105 />
153106 )
@@ -169,15 +122,28 @@ const segmentsVariants = cva("flex w-full gap-1", {
169122
170123function ProgressSegments ( {
171124 className,
125+ value,
126+ min,
127+ max,
172128 ...props
173- } : React . ComponentProps < "div" > ) {
174- const { size, edge, value, min, max } = useProgress ( )
129+ } : React . ComponentProps < "div" > & {
130+ value : number | null
131+ min : number
132+ max : number
133+ } ) {
175134 const percentage = value === null ? 0 : ( ( value - min ) / ( max - min ) ) * 100
176135 const filledCount = Math . round ( ( percentage / 100 ) * SEGMENT_COUNT )
177136 return (
178137 < div
179138 data-slot = "progress-segments"
180- className = { cn ( segmentsVariants ( { size } ) , className ) }
139+ className = { cn (
140+ "flex w-full gap-1" ,
141+ "group-data-[size=sm]/progress:h-0.5" ,
142+ "group-data-[size=default]/progress:h-1" ,
143+ "group-data-[size=lg]/progress:h-2" ,
144+ "group-data-[size=xl]/progress:h-3" ,
145+ className
146+ ) }
181147 { ...props }
182148 >
183149 { Array . from ( { length : SEGMENT_COUNT } ) . map ( ( _ , i ) => {
@@ -192,9 +158,10 @@ function ProgressSegments({
192158 className = { cn (
193159 "h-full flex-1 transition-colors" ,
194160 isFilled ? "bg-primary" : "bg-secondary" ,
195- edge === "round-edge" && "rounded-full" ,
196- edge === "square-edge" && isFirst && "rounded-l-full" ,
197- edge === "square-edge" && isLast && "rounded-r-full"
161+ "group-data-[edge=round-edge]/progress:rounded-full" ,
162+ "group-data-[edge=square-edge]/progress:rounded-none" ,
163+ "group-data-[edge=square-edge]/progress:first:rounded-l-full" ,
164+ "group-data-[edge=square-edge]/progress:last:rounded-r-full"
198165 ) }
199166 />
200167 )
0 commit comments