The Skeleton Loading kit can be used an intermediate loading state to give users a visual indication that content is loading.
Please Note: this kit is not meant to be integrated interally within other Playbook kits as a loading prop; rather, it can be used to create a composite of the section/kit/page with loading intermediataries, as demonstrated in the the "example component" doc examples.
The SkeletonLoading component has a default and a white color
variant.
import React from 'react' import { Card, SkeletonLoading } from "playbook-ui" const SkeletonLoadingColor = (props) => ( <div> <Card borderNone > <SkeletonLoading/> </Card> <Card background="light" borderNone > <SkeletonLoading color="white" /> </Card> </div> ) export default SkeletonLoadingColor
Use the stack
and gap
props in conjunction to layer multiple Skeleton loading bars on top of each other.
stack
accepts a number that correlates to the number of rows (1 is default), and gap
accepts a portion of our spacing props (xxs
as default, xs
, sm
, md
, lg
, xl
, xxl
) to set the pixel distance between each row. gap
will not do anything if there is no corresponding stack
prop set.
The borderRadius
prop accepts all of our BorderRadius tokens, with sm
as default.
import React from 'react' import { Flex, SkeletonLoading } from "playbook-ui" const SkeletonLoadingBorderRadius = (props) => ( <Flex justify="evenly"> <SkeletonLoading borderRadius="rounded" height="50px" width="100px" /> <SkeletonLoading borderRadius="xl" height="50px" width="100px" /> <SkeletonLoading borderRadius="lg" height="50px" width="100px" /> <SkeletonLoading borderRadius="md" height="50px" width="100px" /> <SkeletonLoading height="50px" width="100px" /> <SkeletonLoading borderRadius="xs" height="50px" width="100px" /> <SkeletonLoading borderRadius="none" height="50px" width="100px" /> </Flex> ) export default SkeletonLoadingBorderRadius
The height
and width
props accept pixel and percentage values. If using a percentage for height
, the parent container must have a set height.
Set the height
and width
props to the same value to make a square. A rounded
borderRadius will make a square a circle. If using percentages to make a square, your parent container must also be a square.
import React from 'react' import { Card, SkeletonLoading } from "playbook-ui" const SkeletonLoadingHeightWidth = (props) => ( <div> <SkeletonLoading height="100px" width="50%" /> <SkeletonLoading gap="md" height="20px" marginY="md" stack="3" width="50px" /> <Card height='200px' marginBottom="md" padding="none" width='100%' > <SkeletonLoading borderRadius="md" gap="xl" height="50%" width="300px" /> </Card> <Card height='200px' padding="none" width='100%' > <SkeletonLoading borderRadius="md" gap="xl" height="30%" stack="2" width="70%" /> </Card> <SkeletonLoading height="150px" marginY="md" width="150px" /> <SkeletonLoading borderRadius="rounded" height="150px" width="150px" /> </div> ) export default SkeletonLoadingHeightWidth
import React, { useState } from 'react'; import { Button, Flex, SkeletonLoading, User } from "playbook-ui"; const SkeletonLoadingUser = (props) => { const [isLoading, setIsLoading] = useState(true) const toggleLoading = () => setIsLoading((prev) => !prev) return ( <div> <Button marginBottom="md" onClick={toggleLoading} variant="secondary" > {isLoading ? "Show User" : "Show Skeleton Loading"} </Button> <div> {isLoading ? ( <Flex alignItems="center"> <SkeletonLoading borderRadius="rounded" height="38px" paddingRight="sm" width="38px" /> <SkeletonLoading gap="xxs" height="18px" stack="2" width="161px" /> </Flex> ) : ( <User align="left" avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Anna Black" orientation="horizontal" title="Remodeling Consultant" /> )} </div> <div> {isLoading ? ( <Flex alignItems="start" paddingTop="md" > <Flex alignItems="center" flexDirection="column" > <SkeletonLoading borderRadius="rounded" height="80px" paddingBottom="xs" width="80px" /> <SkeletonLoading height="32px" paddingBottom="xxs" width="144px" /> <SkeletonLoading height="21px" width="164px" /> </Flex> </Flex> ) : ( <Flex alignItems="start" paddingTop="md" > <User align="center" avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Anna Black" orientation="vertical" size="lg" title="Remodeling Consultant" /> </Flex> )} </div> </div> ) } export default SkeletonLoadingUser;
import React, { useState } from 'react'; import { Button, Card, Filter, Flex, Select, SkeletonLoading, TextInput } from "playbook-ui"; const SortingChangeCallback = (sortOptions) => { alert(JSON.stringify(sortOptions[0])) } const SkeletonLoadingFilter = (props) => { const [isLoading, setIsLoading] = useState(true) const toggleLoading = () => setIsLoading((prev) => !prev) const options = [ { value: 'USA' }, { value: 'Canada' }, { value: 'Brazil' }, { value: 'Philippines' }, { value: 'A galaxy far far away, like really far away...' }, ] return ( <div> <Button marginBottom="md" onClick={toggleLoading} variant="secondary" > {isLoading ? "Show Filter" : "Show Skeleton Loading"} </Button> <div> {isLoading ? ( <Card marginBottom="lg" > <Flex alignItems="center" justify="between" orientation="row" > <Flex alignItems="center" justify="start" orientation="row" > <SkeletonLoading borderRadius="rounded" height="40px" marginRight="sm" width="40px" /> <SkeletonLoading height="16px" marginRight="md" width="80px" /> </Flex> <Flex alignItems="center" justify="end" orientation="row" > <SkeletonLoading height="18px" width="120px" /> </Flex> </Flex> </Card> ) : ( <Filter filters={{ 'Full Name': 'John Wick' }} marginBottom="lg" minWidth="375px" results={546} sortOptions={{ popularity: 'Popularity', // eslint-disable-next-line manager_title: 'Manager\'s Title', // eslint-disable-next-line manager_name: 'Manager\'s Name', }} sortValue={[{ name: 'popularity', dir: 'desc' }]} > {({ closePopover }) => ( <form> <TextInput label="Example Text Field" placeholder="Enter Text" /> <Select blankSelection="Select One..." label="Example Collection Select" name="Collection Select" options={options} /> <Flex spacing="between"> <Button onClick={closePopover} text="Filter" /> <Button text="Defaults" variant="secondary" /> </Flex> </form> )} </Filter> )} </div> <div> {isLoading ? ( <SkeletonLoading height="127px" marginBottom="lg" width="100%" /> ) : ( <Filter double filters={{ 'Full Name': 'John Wick', 'City': 'San Francisco', }} marginBottom="xl" minWidth="375px" onSortChange={SortingChangeCallback} results={1} sortOptions={{ popularity: 'Popularity', // eslint-disable-next-line manager_title: 'Manager\'s Title', // eslint-disable-next-line manager_name: 'Manager\'s Name', }} sortValue={[{ name: 'popularity', dir: 'desc' }]} > {({ closePopover }) => ( <form> <TextInput label="Full Name" placeholder="Enter name" /> <Select blankSelection="Select One..." label="Territory" maxWidth="sm" name="location" options={options} /> <Flex spacing="between"> <Button onClick={closePopover} text="Filter" /> <Button text="Defaults" variant="secondary" /> </Flex> </form> )} </Filter> )} </div> </div> ) } export default SkeletonLoadingFilter;