CircularProgress
Renders a circular loading indicator. Supports indeterminate (looping) and determinate (value-driven) variants.
Renders a circular loading indicator. Supports indeterminate (looping) and determinate (value-driven) variants. The stroke color is set via CSS currentColor; the color prop resolves to theme.palette[color].main.
Architecture: the root element is a <span> (not <svg>). This avoids a TypeScript incompatibility between SVGAttributes.height and LayoutProps.height. The internal <svg> fills the span via width/height="100%" and uses a fixed viewBox="0 0 44 44" coordinate system - the size prop scales the outer span via CSS width/height.
Examples
Default
<CircularProgress variant="indeterminate" color="primary" size={40} />
Determinate
<CircularProgress variant="determinate" color="primary" size={40} value={70} />
Spinning Determinate
25%
50%
75%
<Flex flexDirection="row" gap={4} alignItems="center"> {([25, 50, 75] as const).map((value) => ( <Flex key={value} flexDirection="column" alignItems="center" gap={1}> <CircularProgress variant="determinate" value={value} spinning size={48} /> <Typography variant="caption" color="secondary" m={0}> {value}% </Typography> </Flex> ))} </Flex>
Colors
primary
secondary
success
error
info
warning
<Flex flexDirection="column" gap={3}> {(['primary', 'secondary', 'success', 'error', 'info', 'warning'] as const).map((color) => ( <Flex key={color} flexDirection="row" gap={2} alignItems="center"> <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}> {color} </Typography> <CircularProgress showTrack color={color} size={32} /> <CircularProgress showTrack variant="determinate" value={65} color={color} size={32} /> </Flex> ))} </Flex>
Sizes
16px
24px
40px
64px
80px
<Flex flexDirection="row" gap={3} alignItems="end" flexWrap="wrap"> {([16, 24, 40, 64, 80] as const).map((size) => ( <Flex key={size} flexDirection="column" alignItems="center" gap={1}> <CircularProgress size={size} /> <Typography variant="caption" color="secondary" m={0}> {size}px </Typography> </Flex> ))} </Flex>
Thickness
1
2
3.6
6
10
<Flex flexDirection="row" gap={3} alignItems="center" flexWrap="wrap"> {([1, 2, 3.6, 6, 10] as const).map((thickness) => ( <Flex key={thickness} flexDirection="column" alignItems="center" gap={1}> <CircularProgress thickness={thickness} size={48} /> <Typography variant="caption" color="secondary" m={0}> {thickness} </Typography> </Flex> ))} </Flex>
Show Track
indeterminate
determinate 65%
<Flex flexDirection="row" gap={4} alignItems="center" flexWrap="wrap"> <Flex flexDirection="column" alignItems="center" gap={1}> <CircularProgress showTrack size={48} /> <Typography variant="caption" color="secondary" m={0}> indeterminate </Typography> </Flex> <Flex flexDirection="column" alignItems="center" gap={1}> <CircularProgress variant="determinate" value={65} showTrack size={48} /> <Typography variant="caption" color="secondary" m={0}> determinate 65% </Typography> </Flex> </Flex>
Easing
linear
ease
ease-in
ease-out
ease-in-out
<Flex flexDirection="row" gap={4} alignItems="center" flexWrap="wrap"> {(['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out'] as const).map((easing) => ( <Flex key={easing} flexDirection="column" alignItems="center" gap={1}> <CircularProgress easing={easing} size={48} /> <Typography variant="caption" color="secondary" m={0}> {easing} </Typography> </Flex> ))} </Flex>
Custom Range
3 of 10
120 of 200
7 of 5-15
<Flex flexDirection="column" gap={3}> {( [ { value: 3, min: 0, max: 10, label: '3 of 10' }, { value: 120, min: 0, max: 200, label: '120 of 200' }, { value: 7, min: 5, max: 15, label: '7 of 5-15' }, ] as const ).map(({ value, min, max, label }) => ( <Flex key={label} flexDirection="row" gap={2} alignItems="center"> <CircularProgress variant="determinate" value={value} min={min} max={max} showTrack size={48} /> <Typography variant="caption" color="secondary" m={0}> {label} </Typography> </Flex> ))} </Flex>
Spinning With Track
25%
50%
75%
90%
<Flex flexDirection="row" gap={4} alignItems="center" flexWrap="wrap"> {([25, 50, 75, 90] as const).map((value) => ( <Flex key={value} flexDirection="column" alignItems="center" gap={1}> <CircularProgress variant="determinate" value={value} spinning showTrack size={56} thickness={5} /> <Typography variant="caption" color="secondary" m={0}> {value}% </Typography> </Flex> ))} </Flex>
Disable Shrink
default
disableShrink
<Flex flexDirection="row" gap={4} alignItems="center"> <Flex flexDirection="column" alignItems="center" gap={1}> <CircularProgress /> <Typography variant="caption" color="secondary" m={0}> default </Typography> </Flex> <Flex flexDirection="column" alignItems="center" gap={1}> <CircularProgress disableShrink /> <Typography variant="caption" color="secondary" m={0}> disableShrink </Typography> </Flex> </Flex>