# Loading Skeleton (/components/feedback/loading-skeleton)



Use `LoadingSkeleton` when content is loading but its layout is known. Wrap the content that will
appear so the placeholder occupies the same space.

apps/docs/src/examples/loading-skeleton/basic.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { Checkbox } from '@luke-ui/react/checkbox';
import { LoadingSkeleton } from '@luke-ui/react/loading-skeleton';
import { Text } from '@luke-ui/react/text';
import { useState } from 'react';

export default () => {
	const [isLoading, setIsLoading] = useState(true);

	return (
		<Box display="grid" gap="sp16" maxInlineSize="28rem">
			<Checkbox isSelected={isLoading} onChange={setIsLoading}>
				Show loading state
			</Checkbox>
			<Text>
				<LoadingSkeleton isLoading={isLoading}>
					This text wraps across several lines to show how the skeleton follows the final content.
				</LoadingSkeleton>
			</Text>
		</Box>
	);
};
```

Wrap text directly when it spans several lines. The skeleton then follows the final line breaks.

## With components [#with-components]

Wrap a fixed-size element to keep its shape while it loads.

apps/docs/src/examples/loading-skeleton/custom-dimensions.tsx

```tsx
import { Box } from '@luke-ui/react/box';
import { LoadingSkeleton } from '@luke-ui/react/loading-skeleton';

export default () => {
	return (
		<Box display="flex" gap="sp8">
			<LoadingSkeleton>
				<Box blockSize="3rem" borderRadius="full" inlineSize="3rem" />
			</LoadingSkeleton>
			<LoadingSkeleton>
				<Box blockSize="3rem" borderRadius="full" inlineSize="3rem" />
			</LoadingSkeleton>
			<LoadingSkeleton>
				<Box blockSize="3rem" borderRadius="full" inlineSize="3rem" />
			</LoadingSkeleton>
		</Box>
	);
};
```

Set `radius` when the direct child has square corners but a visible descendant has rounded corners.
Use `radius="control"` for a `TextField`, whose input control has rounded corners inside the field
wrapper.

apps/docs/src/examples/loading-skeleton/border-radius.tsx

```tsx
import { Checkbox } from '@luke-ui/react/checkbox';
import { LoadingSkeleton } from '@luke-ui/react/loading-skeleton';
import { Stack } from '@luke-ui/react/stack';
import { TextField } from '@luke-ui/react/text-field';
import { useState } from 'react';

export default () => {
	const [isLoading, setIsLoading] = useState(true);

	return (
		<Stack gap="sp16" maxInlineSize="20rem">
			<Checkbox isSelected={isLoading} onChange={setIsLoading}>
				Show loading state
			</Checkbox>
			<LoadingSkeleton isLoading={isLoading} radius="control">
				<TextField label="Email address" name="email" placeholder="you@example.com" />
			</LoadingSkeleton>
		</Stack>
	);
};
```

## Provider [#provider]

Use `LoadingSkeletonProvider` when one loading state controls a section. Pass `isLoading` to a child
when it needs a different loading state.

apps/docs/src/examples/loading-skeleton/provider.tsx

```tsx
import { Checkbox } from '@luke-ui/react/checkbox';
import { Code } from '@luke-ui/react/code';
import { LoadingSkeleton, LoadingSkeletonProvider } from '@luke-ui/react/loading-skeleton';
import { Stack } from '@luke-ui/react/stack';
import { Text } from '@luke-ui/react/text';
import { useState } from 'react';

export default () => {
	const [isLoading, setIsLoading] = useState(true);

	return (
		<Stack gap="sp16" maxInlineSize="28rem">
			<Checkbox isSelected={isLoading} onChange={setIsLoading}>
				Show loading state
			</Checkbox>
			<LoadingSkeletonProvider isLoading={isLoading}>
				<Stack gap="sp8">
					<Text>
						<LoadingSkeleton>
							This skeleton uses the loading state from its provider.
						</LoadingSkeleton>
					</Text>
					<Text>
						<LoadingSkeleton isLoading={false}>
							This skeleton has <Code>isLoading</Code> explicitly set to <Code>false</Code>, so
							remains visible while its provider is loading.
						</LoadingSkeleton>
					</Text>
				</Stack>
			</LoadingSkeletonProvider>
		</Stack>
	);
};
```

## Element type [#element-type]

`LoadingSkeleton` renders a `span` by default. Set `elementType` when the parent requires another
element, such as an `li` inside a list.

apps/docs/src/examples/loading-skeleton/element.tsx

```tsx
import { LoadingSkeleton } from '@luke-ui/react/loading-skeleton';
import { Stack } from '@luke-ui/react/stack';

export default () => {
	return (
		<Stack elementType="ul" gap="sp8">
			<LoadingSkeleton elementType="li">List item 1</LoadingSkeleton>
			<LoadingSkeleton elementType="li">List item 2</LoadingSkeleton>
			<LoadingSkeleton elementType="li">List item 3</LoadingSkeleton>
		</Stack>
	);
};
```

## Accessibility [#accessibility]

While loading, `LoadingSkeleton` hides its content from assistive technology and blocks focus and
pointer input. It shows the content again when `isLoading` is `false`.

## API [#api]

### LoadingSkeletonProps [#loadingskeletonprops]

<ComponentPropsTable
  id="type-table-loading-skeleton.tsx-LoadingSkeletonProps"
  type="{
  &#x22;id&#x22;: &#x22;loading-skeleton.tsx-LoadingSkeletonProps&#x22;,
  &#x22;name&#x22;: &#x22;LoadingSkeletonProps&#x22;,
  &#x22;description&#x22;: &#x22;Props for `LoadingSkeleton`.&#x22;,
  &#x22;entries&#x22;: [
    {
      &#x22;name&#x22;: &#x22;elementType&#x22;,
      &#x22;description&#x22;: &#x22;Element rendered while loading.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;'span'&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;ElementType | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;isLoading&#x22;,
      &#x22;description&#x22;: &#x22;Whether the skeleton is shown in place of `children`. Overrides a `LoadingSkeletonProvider` ancestor.&#x22;,
      &#x22;tags&#x22;: [
        {
          &#x22;name&#x22;: &#x22;default&#x22;,
          &#x22;text&#x22;: &#x22;true&#x22;
        }
      ],
      &#x22;type&#x22;: &#x22;boolean | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;radius&#x22;,
      &#x22;description&#x22;: &#x22;Sets the semantic corner radius of the skeleton overlay. Use when the wrapped child has no\nradius of its own but a visual descendant does (e.g. wrapping a `TextField`).&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;\&#x22;control\&#x22; | \&#x22;detail\&#x22; | \&#x22;full\&#x22; | \&#x22;overlay\&#x22; | \&#x22;surface\&#x22; | undefined&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: false,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;deprecated&#x22;: false,
      &#x22;description&#x22;: &#x22;`LoadingSkeletonProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.&#x22;,
      &#x22;name&#x22;: &#x22;__nativePropsForwarding&#x22;,
      &#x22;required&#x22;: true,
      &#x22;simplifiedType&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;&#x22;
    }
  ]
}"
/>

### LoadingSkeletonProviderProps [#loadingskeletonproviderprops]

<ComponentPropsTable
  id="type-table-loading-skeleton.tsx-LoadingSkeletonProviderProps"
  type="{
  &#x22;id&#x22;: &#x22;loading-skeleton.tsx-LoadingSkeletonProviderProps&#x22;,
  &#x22;name&#x22;: &#x22;LoadingSkeletonProviderProps&#x22;,
  &#x22;description&#x22;: &#x22;Props for `LoadingSkeletonProvider`.&#x22;,
  &#x22;entries&#x22;: [
    {
      &#x22;name&#x22;: &#x22;children&#x22;,
      &#x22;description&#x22;: &#x22;&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;ReactNode&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;ReactNode&#x22;,
      &#x22;required&#x22;: true,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;isLoading&#x22;,
      &#x22;description&#x22;: &#x22;Default loading state for descendant `LoadingSkeleton` components without an `isLoading` prop.&#x22;,
      &#x22;tags&#x22;: [],
      &#x22;type&#x22;: &#x22;boolean&#x22;,
      &#x22;simplifiedType&#x22;: &#x22;union&#x22;,
      &#x22;required&#x22;: true,
      &#x22;deprecated&#x22;: false
    }
  ]
}"
/>
