Dialog

The Dialog component is used to display a modal dialog that requires user interaction.

Component

Storybook

Storybook - Dialog Documentation

Figma Demo

Guidelines

Intent

Dialogs are intended to notify users in a more intrusive way than an alert. They block other screen content and require action to dismiss.

Variations

There is are two variations of the dialog component, default and minimal. The default variant has a minimum and maximum width to control its size, and a maximum height for its content area to ensure that it will scroll if the content is long. The minimal variant is an empty version of the dialog that is used for simple confirmations or alerts that do not require additional information.

Note: While there is only one variation of the dialog in code, there are two variants within Figma. This is to allow designers to use the mobile version on smaller screens, which uses the stretch variant of our button component.

Usage

Only use dialogs for critically important messaging that requires user attention and decision. Examples might include an ongoing issue with site performance or the necessary step of choosing a pickup date after order submission for a pickup order.

For more task-based activity, consider using the Task Panel. More often than not, the use of modals in Fizz would be better served by the Task Panel component.

Best Practices

  • Use dialogs for messaging purposes when something is important enough to briefly interrupt the user’s experience.
  • Do not use dialogs for task completion such as filling out forms or exploring product details.

Accessibility

The autofocus attribute should be added to the element the user is expected to interact with immediately upon opening a modal dialog. If no other element involves more immediate interaction, it is recommended to add autofocus to the close button inside the dialog or to the dialog itself if the user is expected to click/activate it to dismiss.

Content

Dialogs are designed to allow for content to scroll, but as with other components within the communication category, keep the content as short and clear as possible. Dialogs block content and interrupt the experience, creating more pressure to be direct.

Default Dialogs must have both a title and a description. Use the title area for the clearest communication of the dialog’s intent, and the description only as supporting information. Assume that users are only reading the title.

Minimal Dialogs are designed to be used when the header and footer are not necessary. They are used for simple confirmations or alerts that do not require additional information.

Component Specs

API

  • class: string Any additional classes to be added to the Dialog, Minimal variant only.

  • closeBtnClick: function
    Function to be called when the close button is clicked.

  • description: string | Default: 'Description paragraph goes here, try to keep it short and digestible.'
    Description of the dialog.

  • open: boolean | Default: false
    Whether the dialog is open or not.

  • primaryClick: function
    Function to be called when the primary button is clicked.

  • primaryLabel: string | Default: 'Confirm'
    Label of the primary button.

  • primaryType: HTMLButtonAttributes[type] | Default: 'button'
    Type of the primary button.

  • title: string | Default: 'Title'
    Title of the dialog.

  • testId: string | Default: undefined
    Test id for the dialog.

  • variant: default | minimal | Default: 'default'
    Variant of the dialog.

Example

<script>
	import { Button, Dialog } from '@getprovi/craft-svelte';
	let open = false;
</script>

<Button label="Open Defaul" on:click={() => (open = true)} />
<Dialog
	bind:open
	title="Dialog Title"
	description="Dialog Description"
	primaryLabel="Confirm"
	primaryClick={() => {}}
	closeBtnClick={() => {}}
	on:close={() => console.log('closed')}>Some content to confirm</Dialog
>
<Button label="Open Minimal" on:click={() => (open = true)} />
<Dialog bind:open variant="minimal" data-testid="test-dialog" />

Types

interface Shared {
	backgroundBlur?: boolean;
	open?: boolean;
	testId?: string | undefined;
}

interface Minimal extends Shared {
	variant: 'minimal';
	class?: string | undefined | null;
	closeBtnClick?: never;
	description?: never;
	primaryClick?: never;
	primaryLabel?: never;
	primaryType?: never;
	title?: never;
}

interface Default extends Shared {
	variant?: 'default';
	closeBtnClick?: () => void;
	description?: string;
	primaryClick: () => void;
	primaryLabel: string;
	primaryType?: HTMLButtonAttributes['type'];
	title: string;
	class?: never;
}

type Props = Default | Minimal;