Acronis UIKit
Components

DialogWelcome

An onboarding/announcement dialog with a feature carousel or a single-slide layout.

Usage

import { DialogWelcome } from '@acronis-platform/ui-react';

DialogWelcome is the sanctioned way to build an onboarding or feature-announcement dialog. A variant prop selects one of two Figma-defined layouts: 'carousel' (default) steps through slides — each an image/title/description — via a DialogFooterCarousel bar with Back/Next/dot navigation (or by dragging or swiping the slide itself) and a call-to-action button on the last slide; 'single' renders one image/title/description with a Close link and a call-to-action button, no footer bar. It's built internally on Base UI's Dialog primitive (focus trap, scroll lock, Esc/outside-press dismissal, and ARIA come from Base UI), but that primitive is not itself exported.

Examples

A controlled carousel dialog. onPrimaryAction fires when the last slide's call-to-action button is clicked — the dialog doesn't close on its own, so close it yourself once the action completes:

const [open, setOpen] = useState(false);

const slides = [
  { title: 'Automated backups', description: 'Your data is backed up on a schedule you control.' },
  { title: 'Instant recovery', description: 'Restore a full workload in minutes, not hours.' },
  { title: 'Built-in protection', description: 'Ransomware detection runs on every backup automatically.' },
];

<DialogWelcome
  variant="carousel"
  slides={slides}
  open={open}
  onOpenChange={setOpen}
  onPrimaryAction={() => setOpen(false)}
/>;

Control the active slide with selectedIndex, e.g. to resume onboarding where a user left off. Always pair it with onSelectedIndexChange: the Back/Next/dot controls only ever report the index they want, they never move the carousel themselves. Without the handler the dialog is pinned to selectedIndex — clicks do nothing and a drag snaps back, so the visible slide can't drift away from the one carrying the dialog's accessible name:

const [slideIndex, setSlideIndex] = useState(1);

<DialogWelcome
  variant="carousel"
  slides={slides}
  selectedIndex={slideIndex}
  onSelectedIndexChange={setSlideIndex}
  open
  onOpenChange={setOpen}
/>;

onSelectedIndexChange fires exactly once per navigation, so each call maps to a single user action — safe to forward straight to analytics. Uncontrolled, it also fires once on mount with the starting index (0); controlled, it stays silent on mount because the carousel already opens on selectedIndex.

The single layout — one slide, a Close link instead of carousel navigation:

<DialogWelcome
  variant="single"
  title="New: Instant recovery"
  description="Restore a full workload in minutes, not hours."
  primaryLabel="Try it now"
  onPrimaryAction={() => setOpen(false)}
  open
  onOpenChange={setOpen}
/>

Pass each slide's own illustration/media via image:

<DialogWelcome
  variant="carousel"
  slides={slides.map((slide, index) => ({ ...slide, image: <img src={`/slide-${index}.png`} alt="" /> }))}
  open
  onOpenChange={setOpen}
/>

When the dialog renders inside an isolated container (e.g. a shadow root), pass a portalContainer so the popup inherits that scope's styles:

<DialogWelcome portalContainer={mountNode} open onOpenChange={setOpen} />

When to use

  • First-run onboarding that introduces a few key features one at a time.
  • A single feature-announcement modal shown once (e.g. after a release).

When not to use

  • For a task the user must complete or acknowledge before proceeding (rename, confirm, discard changes) — use Dialog.

API Reference

Prop

Type

Edit on GitHub

On this page