The color at the animation end
Skeleton
Skeleton is used to display the loading state of some component.
Import#
import { Skeleton, SkeletonCircle, SkeletonText } from '@chakra-ui/react'
Usage#
You can use it as a standalone component.
<Stack><Skeleton height='20px' /><Skeleton height='20px' /><Skeleton height='20px' /></Stack>
Or to wrap another component to take the same height and width.
<Skeleton><div>contents wrapped</div><div>won't be visible</div></Skeleton>
Useful when fetching remote data.
import { Box } from '@chakra-ui/react'function Card() {const { data, loading, error } = useRemoteData()if (error) return <Box children='error' />return (<Box><Skeleton isLoaded={!loading}><Heading>{data.title}</Heading></Skeleton></Box>)}
Circle and Text Skeleton#
<Box padding='6' boxShadow='lg' bg='white'><SkeletonCircle size='10' /><SkeletonText mt='4' noOfLines={4} spacing='4' skeletonHeight='2' /></Box>
Skeleton color#
You can change the animation color with startColor and endColor.
<Skeleton startColor='pink.500' endColor='orange.500' height='20px' />
Skipping the skeleton when content is loaded#
You can prevent the skeleton from rendering using the isLoaded prop.
<Skeleton isLoaded><span>Chakra ui is cool</span></Skeleton>
fadeDuration with isLoaded#
With the fadeDuration prop, you can control the duration of the content fading
into view. The value in this prop is a number representing seconds which is part
of the animation style prop that is rendered to the component. Default value
is 0.4 seconds.
This requires the isLoaded prop, and the animation is best visible when the
isLoaded prop is toggled to true.
function Example() {const [isLoaded, setIsLoaded] = React.useState(false)return (<Stack padding={4} spacing={1}><Skeleton height='40px' isLoaded={isLoaded}><Box>Hello World!</Box></Skeleton><Skeletonheight='40px'isLoaded={isLoaded}bg='green.500'color='white'fadeDuration={1}><Box>Hello React!</Box></Skeleton><Skeletonheight='40px'isLoaded={isLoaded}fadeDuration={4}bg='blue.500'color='white'><Box>Hello ChakraUI!</Box></Skeleton><Box textAlign='center'><Button onClick={() => setIsLoaded((v) => !v)}>toggle</Button></Box></Stack>)}
Props#
endColor
endColorstringfadeDuration
fadeDurationThe fadeIn duration in seconds. Requires isLoaded toggled to true in order to see the transition.
number0.4fitContent
fitContentIf true, the skeleton will take the width of it's children
booleanfalseisLoaded
isLoadedIf true, it'll render its children with a nice fade transition
booleanfalsespeed
speedThe animation speed in seconds
number0.8startColor
startColorThe color at the animation start
stringThe Skeleton component is a single part component. All of the styling is
applied directly to the Skeleton element.
To learn more about styling single part components, visit the Component Style page.
Theming properties#
The properties that affect the theming of the Skeleton component are:
variant: The visual variant of the skeleton.colorScheme: The color scheme of the skeleton.size: The size of the skeleton.
Theming utilities#
defineStyle: a function used to create style objects.defineStyleConfig: a function used to define the style configuration for a single part component.
import { defineStyle, defineStyleConfig } from '@chakra-ui/react'
Adding a custom variant#
import { defineStyle, defineStyleConfig, cssVar } from '@chakra-ui/react'const $startColor = cssVar('skeleton-start-color')const $endColor = cssVar('skeleton-end-color')const red = defineStyle({_light: {[$startColor.variable]: 'colors.red.100', //changing startColor to red.100[$endColor.variable]: 'colors.red.400', // changing endColor to red.400},_dark: {[$startColor.variable]: 'colors.red.800', //changing startColor to red.800[$endColor.variable]: 'colors.red.600', // changing endColor to red.600},})export const skeletonTheme = defineStyleConfig({variants: { red },})
After customizing the skeleton theme, we can import it in our theme file and add
it in the components property:
import { extendTheme } from '@chakra-ui/react'import { skeletonTheme } from './components/skeleton'export const theme = extendTheme({components: { Skeleton: skeletonTheme },})
This is a crucial step to make sure that any changes that we make to the skeleton theme are applied.
Adding a custom size#
Let's assume we want to include an extra large skeleton size. Here's how we can do that:
import { defineStyle, defineStyleConfig } from '@chakra-ui/react'const xl = defineStyle({h: 9,borderRadius: 'lg',})export const skeletonTheme = defineStyleConfig({sizes: { xl },})// Now we can use the new `xl` size<Skeleton size="xl">...</Skeleton>
Every time you're adding anything new to the theme, you'd need to run the CLI command to get proper autocomplete in your IDE. You can learn more about the CLI tool here.
Changing the default properties#
Let's assume we want to change the default size or variant of every Skeleton in our app. Here's how we can do that:
import { defineStyleConfig } from '@chakra-ui/react'export const skeletonTheme = defineStyleConfig({defaultProps: {size: 'xl',variant: 'red',},})// This saves you time, instead of manually setting the size,// variant and color scheme every time you use a skeleton:<Skeleton size="lg" variant="red">...</Skeleton>
Showcase#
import { Text, Box, Flex, Skeleton, Button, IconButton, useColorMode, } from "@chakra-ui/react"; import { FaMoon, FaSun } from "react-icons/fa"; import { useState } from "react"; export default function App() { const [isLoading, setIsLoading] = useState(true); const { toggleColorMode, colorMode } = useColorMode(); return ( <Box pos="relative" height="100vh"> <Flex textAlign="center" gap={6} p={8} direction="column"> <Box> <Skeleton p={0.5} borderRadius="md" bg="teal.500" isLoaded={!isLoading} fadeDuration={1}> <Text color="teal.100" fontWeight="500">Default Skeleton</Text> </Skeleton> </Box> <Box> <Skeleton isLoaded={!isLoading} bg='green.500' fadeDuration={1.5} size="xl" borderRadius="sm" p={2} > <Text color="green.100" fontWeight="500">Custom size</Text> </Skeleton> </Box> <Box> <Skeleton isLoaded={!isLoading} fadeDuration={2} variant="red" background='red.500' borderRadius="xl" > <Text color="red.100" fontWeight={500}>Custom red variant</Text> </Skeleton> </Box> <Box> <Button colorScheme="gray" variant="outline" onClick={() => setIsLoading(!isLoading)} > Toggle loading state </Button> </Box> </Flex> <IconButton aria-label="toggle theme" rounded="full" size="xs" position="absolute" bottom={4} left={4} onClick={toggleColorMode} icon={colorMode === "dark" ? <FaSun /> : <FaMoon />} /> </Box> ); }