> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# SplashScreen

The full-screen entrance for a cold start — the brand `Logo` over an indeterminate bar, shown once while the app boots. Never on a route change and never as a general loading veil: in-app waits belong to `Loader`, `Skeleton` or `Progress`, and `AppShell` ships its own first-load reveal, so run one or the other rather than both. You drive `visible` and nothing else — the phases between are internal — and since it enforces no minimum on-screen time, guarding against a flash on a fast boot is the caller’s job.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/SplashScreen) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/loading-splashscreen--overview)

```tsx
import { SplashScreen } from '@wallarm-org/design-system/SplashScreen';

export const Basic = () => <SplashScreen />;
```

## Usage

```tsx
import { SplashScreen } from '@wallarm-org/design-system/SplashScreen';
```

## Examples

### Toggle

Flipping `visible` to false is the whole handover: with no `shrinkTarget` the splash fades out and unmounts, and any children are never shown.

```tsx
import { useState } from 'react';
import { Button } from '@wallarm-org/design-system/Button';
import { SplashScreen } from '@wallarm-org/design-system/SplashScreen';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Toggle = () => {
  const [visible, setVisible] = useState(true);

  return (
    <VStack align='center'>
      <div className='flex h-400 w-400 items-center justify-center'>
        <SplashScreen visible={visible} />
      </div>

      <Button type='button' onClick={() => setVisible(v => !v)}>
        {visible ? 'Hide' : 'Show'}
      </Button>
    </VStack>
  );
};
```

### Shrink to card

With a `shrinkTarget` it morphs into that box and reveals its children inside — the entrance becomes the first view, typically a sign-in card.

```tsx
import { useEffect, useState } from 'react';
import { AnimatedBackground } from '@wallarm-org/design-system/AnimatedBackground';
import { Button } from '@wallarm-org/design-system/Button';
import { SplashScreen } from '@wallarm-org/design-system/SplashScreen';

export const ShrinkToCard = () => {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    if (!visible) return;

    const timer = window.setTimeout(() => {
      setVisible(false);
    }, 2000);

    return () => window.clearTimeout(timer);
  }, [visible]);

  return (
    <div className='relative h-screen w-screen'>
      <AnimatedBackground />

      <div className='absolute inset-0 flex items-center justify-center'>
        <SplashScreen
          visible={visible}
          shrinkTarget={{ width: 480, height: 600, borderRadius: 12 }}
          className='bg-bg-page-bg shadow-lg'
        >
          <div className='flex h-full flex-col items-center justify-center gap-4 p-8'>
            <h2 className='text-lg font-semibold text-text-primary'>Welcome</h2>
            <p className='text-center text-sm text-text-secondary'>
              Content revealed after splash animation.
            </p>
            <Button type='button' onClick={() => setVisible(true)}>
              Replay
            </Button>
          </div>
        </SplashScreen>
      </div>
    </div>
  );
};
```

### Measured height

The splash can measure its own content height when `shrinkTarget.height` is omitted — the animation shrinks to fit whatever you put inside, no hardcoded constant needed.

```tsx
import { useEffect, useState } from 'react';
import { AnimatedBackground } from '@wallarm-org/design-system/AnimatedBackground';
import { Button } from '@wallarm-org/design-system/Button';
import { Input } from '@wallarm-org/design-system/Input';
import { SplashScreen } from '@wallarm-org/design-system/SplashScreen';
import { Text } from '@wallarm-org/design-system/Text';

export const MeasuredHeight = () => {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    if (!visible) return;

    const timer = window.setTimeout(() => {
      setVisible(false);
    }, 2000);

    return () => window.clearTimeout(timer);
  }, [visible]);

  const handleSignIn = () => {
    setVisible(true);
  };

  return (
    <div className='relative h-screen w-screen'>
      <AnimatedBackground />

      <div className='absolute inset-0 flex items-center justify-center'>
        <SplashScreen
          visible={visible}
          shrinkTarget={{ width: 480, borderRadius: 12 }}
          className='bg-bg-page-bg shadow-lg'
        >
          <div className='flex h-full w-full flex-col items-center justify-center gap-16 p-24'>
            <Text size='xl'>Sign In</Text>
            <div className='flex w-full flex-col gap-12'>
              <Input placeholder='Email' />
              <Input placeholder='Password' type='password' />
            </div>
            <Button variant='primary' color='brand' className='w-full' onClick={handleSignIn}>
              Sign In
            </Button>
          </div>
        </SplashScreen>
      </div>
    </div>
  );
};
```

## Props

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| visible        | `boolean \| undefined`                               | `true`  |             |
| shrinkTarget   | `SplashScreenShrinkTarget \| undefined`              |         |             |
| onPhaseChange  | `((phase: PhaseType) => void) \| undefined`          |         |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |
