Skip to content
Esc
navigateopen⌘Jpreview
On this page

Skeleton

Use to show a placeholder while content is loading.

import * as stylex from '@stylexjs/stylex';

import { Skeleton } from '@/components/ui/skeleton';
import { space, container } from '@/lib/constants.stylex';
import { radius } from '@/lib/tokens.stylex';

export default function SkeletonDemo() {
  return (
    <div {...stylex.props(styles.root)}>
      <Skeleton style={styles.avatar} />
      <div {...stylex.props(styles.lines)}>
        <Skeleton style={styles.lineWide} />
        <Skeleton style={styles.line} />
      </div>
    </div>
  );
}

const styles = stylex.create({
  root: {
    alignItems: 'center',
    display: 'flex',
    gap: space.s4,
  },
  avatar: {
    borderRadius: radius.full,
    height: space.s12,
    width: space.s12,
  },
  lines: {
    display: 'flex',
    flexDirection: 'column',
    gap: space.s2,
  },
  lineWide: {
    height: space.s4,
    width: container.xs,
  },
  line: {
    height: space.s4,
    width: space.s16,
  },
});

Install

npx shadcn@latest add @madeui/skeleton

Usage

import { Skeleton } from '@/components/ui/skeleton';

Card

import * as stylex from '@stylexjs/stylex';

import { Skeleton } from '@/components/ui/skeleton';
import { space, container } from '@/lib/constants.stylex';
import { radius } from '@/lib/tokens.stylex';

export default function SkeletonCard() {
  return (
    <div {...stylex.props(styles.root)}>
      <Skeleton style={styles.image} />
      <Skeleton style={styles.lineWide} />
      <Skeleton style={styles.line} />
    </div>
  );
}

const styles = stylex.create({
  root: {
    display: 'flex',
    flexDirection: 'column',
    gap: space.s3,
    width: container.card,
  },
  image: {
    borderRadius: radius.lg,
    height: container.xs,
    width: '100%',
  },
  lineWide: {
    height: space.s4,
    width: '100%',
  },
  line: {
    height: space.s4,
    width: '60%',
  },
});

List

import * as stylex from '@stylexjs/stylex';

import { Skeleton } from '@/components/ui/skeleton';
import { space, container } from '@/lib/constants.stylex';
import { radius } from '@/lib/tokens.stylex';

export default function SkeletonList() {
  return (
    <div {...stylex.props(styles.root)}>
      {Array.from({ length: 3 }, (_, index) => (
        <div key={index} {...stylex.props(styles.row)}>
          <Skeleton style={styles.avatar} />
          <div {...stylex.props(styles.lines)}>
            <Skeleton style={styles.lineWide} />
            <Skeleton style={styles.line} />
          </div>
        </div>
      ))}
    </div>
  );
}

const styles = stylex.create({
  root: {
    display: 'flex',
    flexDirection: 'column',
    gap: space.s4,
    width: container.sm,
  },
  row: {
    alignItems: 'center',
    display: 'flex',
    gap: space.s3,
  },
  avatar: {
    borderRadius: radius.full,
    flexShrink: 0,
    height: space.s10,
    width: space.s10,
  },
  lines: {
    display: 'flex',
    flex: 1,
    flexDirection: 'column',
    gap: space.s2,
  },
  lineWide: {
    height: space.s4,
    width: '70%',
  },
  line: {
    height: space.s4,
    width: '40%',
  },
});

API reference

A plain <div> with a pulse animation. Size and shape it with the style prop (StyleXStyles, merged last) — width, height, and border radius come from your layout.

Was this page helpful?