Skeleton

Use to show a placeholder while content is loading.

Examples

Basic

Preview
Code

Shape

PropDefaultTypeDescription
roundednonestringChange the shape of the skeleton.
Preview
Code

Color

PropDefaultTypeDescription
skeletongraystringChange the color of the skeleton.
Preview
Code

Element

PropDefaultTypeDescription
asdivAsTag, ComponentChange the element the skeleton renders as.
asChildfalsebooleanRender the child element directly instead of a wrapper.

Use as="span" inside a <p> — a div there is invalid and the parser closes the paragraph early, breaking hydration. Add block or inline-block so the span keeps its height.

Preview
Code

Slots

NamePropsDescription
default-The default slot.

Presets

shortcuts/skeleton.ts
import type { RuleContext } from '@unocss/core'
import type { Theme } from '@unocss/preset-uno'
import { parseColor } from '@unocss/preset-mini/utils'

type SkeletonPrefix = 'skeleton'

export const staticSkeleton: Record<`${SkeletonPrefix}-${string}` | SkeletonPrefix, string> = {
  // base
  skeleton: 'text-md animate-pulse rounded-md w-full h-0.5em bg-brand',
}

export const dynamicSkeleton = [
  [/^skeleton-(.*)$/, ([, body]: string[], { theme }: RuleContext<Theme>) => {
    const color = parseColor(body, theme)
    if (color?.color)
      return `n-${body}-100 dark:n-${body}-800`
  }],
]

export const skeleton = [
  ...dynamicSkeleton,
  staticSkeleton,
]

Props

types/skeleton.ts
import type { PrimitiveProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'

interface Extensions { class?: HTMLAttributes['class'] }

export interface NSkeletonProps extends PrimitiveProps, Extensions {
  /**
   * Allows you to add `UnaUI` skeleton preset properties,
   * Think of it as a shortcut for adding options or variants to the preset if available.
   *
   * @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/skeleton.ts
   * @example
   * skeleton="green""
   */
  skeleton?: HTMLAttributes['class']
  /**
   * Allows you to change the size of the skeleton.
   *
   * @default base|md
   *
   * @example
   * size="sm" | size="2cm" | size="2rem" | size="2px"
   */
  size?: HTMLAttributes['class']
  /**
   * Allows you to change the shape of the skeleton.
   * @default rounded
   *
   * @example
   * rounded="none" | rounded="sm" | rounded="md" | rounded="lg" | rounded="full"
   */
  rounded?: HTMLAttributes['class']
  /**
   * `UnaUI` preset configuration
   *
   * @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/skeleton.ts
   */
  una?: {
    skeleton?: HTMLAttributes['class']
  }
}

Components

Skeleton.vue
<script setup lang="ts">
import type { NSkeletonProps } from '../../types'
import { Primitive } from 'reka-ui'
import { cn } from '../../utils'

const props = withDefaults(defineProps<NSkeletonProps>(), {
  skeleton: 'gray',
  as: 'div',
})
</script>

<template>
  <Primitive
    :as
    :as-child
    aria-busy="true"
    :class="
      cn(
        'skeleton',
        props.class,
        props.una?.skeleton,
      )
    "
    :skeleton
    :size
    :rounded
  >
    <slot />
  </Primitive>
</template>