ProgressCircle
A circular visual indicator of completion progress.@coinbase/cds-web@8.21.3
ImportSourceView source code
import { ProgressCircle } from '@coinbase/cds-web/visualizations/ProgressCircle'
Peer dependencies
- framer-motion: ^10.18.0
Related components
Default
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0} size={100} /> <ProgressCircle progress={0.5} size={100} /> <ProgressCircle progress={1} size={100} /> </HStack>
Thin
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0} weight="thin" size={100} /> <ProgressCircle progress={0.5} weight="thin" size={100} /> <ProgressCircle progress={1} weight="thin" size={100} /> </HStack>
Semiheavy
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0} weight="semiheavy" size={100} /> <ProgressCircle progress={0.5} weight="semiheavy" size={100} /> <ProgressCircle progress={1} weight="semiheavy" size={100} /> </HStack>
Heavy
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0} weight="heavy" size={100} /> <ProgressCircle progress={0.5} weight="heavy" size={100} /> <ProgressCircle progress={1} weight="heavy" size={100} /> </HStack>
No Text
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0} hideContent size={25} /> <ProgressCircle progress={0.5} hideContent size={25} /> <ProgressCircle progress={1} hideContent size={25} /> </HStack>
Disabled
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0} disabled size={100} /> <ProgressCircle progress={0.5} disabled size={100} /> <ProgressCircle progress={1} disabled size={100} /> </HStack>
Colors
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0.5} color="bgPositive" size={100} /> <ProgressCircle progress={0.5} color="bgNegative" size={100} /> <ProgressCircle progress={0.5} color="bgPrimary" size={100} /> <ProgressCircle progress={0.5} color="fg" size={100} /> </HStack>
Fill Parent
The progress circle can be dynamically sized to fit its parent. If you drag the browser window smaller or larger then the ProgressCircle will resize accordingly.
Loading...
Live Code<HStack gap={2} flexWrap="wrap"> <div style={{ height: '15vw', width: '15vw', minWidth: '60px', minHeight: '60px' }}> <ProgressCircle progress={1} /> </div> <div style={{ height: '10vw', width: '10vw', minWidth: '60px', minHeight: '60px' }}> <ProgressCircle progress={1} /> </div> <div style={{ height: '5vw', width: '5vw', minWidth: '60px', minHeight: '60px' }}> <ProgressCircle progress={1} /> </div> </HStack>
Content Node Customization
You can override the default content node to display a custom node. Note that the content node is clipped to the circle.
With Asset
You can provide an image, such as an asset, as the content node.
Loading...
Live Code<VStack gap={2}> <HStack gap={2}> <ProgressCircle progress={1} size={56} styles={{ progress: { stroke: assets.eth.color, }, }} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.eth.name} shape="circle" source={assets.eth.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle progress={0.75} size={56} styles={{ progress: { stroke: assets.ltc.color, }, }} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.ltc.name} shape="circle" source={assets.ltc.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle progress={0.5} size={56} styles={{ progress: { stroke: assets.dai.color, }, }} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage shape="circle" source={assets.dai.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle progress={0.25} size={56} styles={{ progress: { stroke: assets.sushi.color, }, }} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.sushi.name} shape="circle" source={assets.sushi.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle progress={0} size={56} styles={{ progress: { stroke: assets.xrp.color, }, }} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.xrp.name} shape="circle" source={assets.xrp.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> </HStack> <HStack gap={2}> <ProgressCircle styles={{ progress: { stroke: assets.btc.color, }, }} progress={0.24} size={24} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.btc.name} shape="circle" source={assets.btc.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle styles={{ progress: { stroke: assets.btc.color, }, }} progress={0.24} size={32} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.btc.name} shape="circle" source={assets.btc.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle styles={{ progress: { stroke: assets.btc.color, }, }} progress={0.24} size={40} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.btc.name} shape="circle" source={assets.btc.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle styles={{ progress: { stroke: assets.btc.color, }, }} progress={0.24} size={48} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.btc.name} shape="circle" source={assets.btc.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> <ProgressCircle styles={{ progress: { stroke: assets.btc.color, }, }} progress={0.24} size={56} contentNode={ <Box height="100%" padding={0.25} width="100%"> <RemoteImage alt={assets.btc.name} shape="circle" source={assets.btc.imageUrl} style={{ width: '100%', height: '100%' }} /> </Box> } weight="thin" /> </HStack> </VStack>
Custom Text Color
The progress circle's default content can be customized to display a custom text color.
Loading...
Live Code<HStack gap={2}> <ProgressCircle color="fgPrimary" progress={0.2} size={100} contentNode={<DefaultProgressCircleContent color="fgPrimary" progress={0.2} />} /> <ProgressCircle color="fgPositive" progress={0.4} size={100} contentNode={<DefaultProgressCircleContent color="fgPositive" progress={0.4} />} /> </HStack>
Custom Styles
The progress circle can be customized with styles and class names.
Loading...
Live Code<HStack gap={2}> <ProgressCircle progress={0.4} size={100} styles={{ circle: { stroke: 'transparent', }, }} contentNode={<TextTitle1 color="fgPrimary">40%</TextTitle1>} weight="semiheavy" /> <ProgressCircle color="fgPositive" progress={0.6} size={100} styles={{ progress: { strokeLinecap: 'square', }, }} contentNode={<Icon color="fgPositive" name="circleCheckmark" size="l" />} /> </HStack>
Interactive Demo
This is for demo purposes. ProgressContainerWithButtons isn't designed for production usage.
Loading...
Live Code<ProgressContainerWithButtons> {({ calculateProgress }) => ( <HStack gap={2}> <ProgressCircle progress={calculateProgress(0)} size={100} /> <ProgressCircle progress={calculateProgress(0.2)} size={100} /> </HStack> )} </ProgressContainerWithButtons>
Animation Callbacks
You can use the onAnimationStart and onAnimationEnd callbacks to track the progress of the animation.
Loading...
Live Codefunction Example() { const [animationStatus, setAnimationStatus] = React.useState('Ready'); const handleAnimationStart = useCallback(() => { setAnimationStatus('Animating...'); }, []); const handleAnimationEnd = useCallback(() => { setAnimationStatus('Animation Ended'); }, []); return ( <ProgressContainerWithButtons> {({ calculateProgress }) => ( <VStack gap={2}> <Text>Animation Status: {animationStatus}</Text> <ProgressCircle onAnimationEnd={handleAnimationEnd} onAnimationStart={handleAnimationStart} progress={calculateProgress(0.2)} size={100} /> </VStack> )} </ProgressContainerWithButtons> ); }