Components
Skeleton

Skeleton

Display a placeholder while content is loading.

Usage

import { Circle, HStack, Stack } from 'styled-system/jsx'
import { Skeleton, type SkeletonProps } from '~/components/ui/skeleton'

export const Demo = (props: SkeletonProps) => {
  return (
    <HStack width="full" gap="4">
      <Skeleton borderRadius="full">
        <Circle size="20" />
      </Skeleton>
      <Stack gap="3.5" width="full">
        <Skeleton h="4" />
        <Skeleton h="4" width="80%" />
        <Skeleton h="4" width="60%" />
      </Stack>
    </HStack>
  )
}

Examples

You can use it as a standalone component or wrap it around other components.

contents wrapped
won't be visible
<Skeleton>
  <div>contents wrapped</div>
  <div>won't be visible</div>
</Skeleton>

Skipping the animation

You can prevent the Skeleton from rendering using the isLoaded prop.

https://park-ui.com
<Skeleton isLoaded>
  <span>https://park-ui.com</span>
</Skeleton>

Installation

Insert code snippet into your project. Update import paths as needed.

import { ark, type HTMLArkProps } from '@ark-ui/react/factory'
import { forwardRef, type ReactNode } from 'react'
import { tv, type VariantProps } from 'tailwind-variants'

export interface SkeletonProps extends HTMLArkProps<'div'>, SkeletonVariantProps {
  children?: ReactNode
  /**
   *
   * @default false
   */
  isLoaded?: boolean
}

export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>((props, ref) => {
  const { isLoaded, className, ...rest } = props

  if (isLoaded) {
    return <ark.div className="animate-fade-in" ref={ref} {...rest} />
  }
  return <ark.div ref={ref} className={styles({ className })} {...rest} />
})

Skeleton.displayName = 'Skeleton'

type SkeletonVariantProps = VariantProps<typeof styles>

const styles = tv({ base: 'skeleton', variants: {} }, { twMerge: false })

Previous

Select