Modals

Utility

High priority dialogs and modals using a dynamic queue system.

Examples

Dialog Modals

Custom Component Modals

Getting Started

Import and add a single instance of the Modal component in your app's root layout. Since this is in global scope it will be possible to reuse this feature throughout your entire application.

html
<Modal />

Modal Store

When you wish to trigger a modal, import the modalStore, which acts as the modal queue.

typescript
import { modalStore } from '@skeletonlabs/skeleton';

Trigger

Note that title, body, and image are optional for all modal types.

typescript
function triggerAlert(): void {
	const alert: ModalSettings = {
		type: 'alert',
		title: 'Example Alert',
		body: 'This is an example modal.',
		image: 'https://i.imgur.com/WOgTG96.gif',
		// Optionally override buttont text
		buttonTextCancel: 'Cancel'
	};
	modalStore.trigger(alert);
}

Close

Trigger the close() method to remove the first modal in the modal queue.

typescript
modalStore.close();

Clear

Trigger the clear() method completely empty the modal queue.

typescript
modalStore.clear();

Debugging the Queue

Use the following technique to visualize the contents of the store for debugging.

html
<pre>queue: {JSON.stringify($modalStore, null, 2)}</pre>

Customizing Modals

To customize an individual modal, append classes and provide the classes you wish to be applied to the modal window.

typescript
const d: ModalSettings = {
	type: 'alert',
	// ...
	backdropClasses: '!items-start',
	modalClasses: '!p-0 !bg-green-500 !max-w-[75%]'
};

Note that ! (important) may be required to override some styles.

Component Modals

Advanced

You can create a custom modal by passing a ModalComponent object, which includes any Svelte component.

typescript
// import MyCustomComponent from '...';

function triggerCustomModal(): void {
	const modalComponent: ModalComponent = {
		// Pass a reference to your custom component
		ref: MyCustomComponent,
		// Add your props as key/value pairs
		props: { background: 'bg-red-500' },
		// Provide default slot content as a template literal
		slot: '<p>Skeleton</p>'
	};
	const d: ModalSettings = {
		type: 'component',
		// NOTE: title, body, response, etc are supported!
		component: modalComponent,
		// Pass abitrary data to the component
		meta: { foo: 'bar', fizz: 'buzz', fn: myCustomFunction }
	};
	modalStore.trigger(d);
}

When constructing custom modals, you are responsible for implementing close/submit buttons, as well as triggering the response method as needed. To make this process easier to understand, we have provided a few examples to demonstrate the process.

View Example Modals

Below are a few tips and recommendations for custom modals:

  • Import and use the modalStore to interface directly with the active modal queue. $modalStore[0] is the visible modal index.
  • Parent props are available via parent - ex: parent.background will provide the background color prop.
  • You can inspect the full list of available parent prop values in the source code.
  • Use the parent.onClose() or modalStore.close() methods to close the modal.
  • Use the $modalStore[0].response('myResponseDataHere'); method to return a response value.

Abitrary Data

Advanced

You can pass abitrary metadata to your modal via the meta setting. All data types are supported.

typescript
const d: ModalSettings = {
	// ...
	meta: { foo: 'bar', fizz: 'buzz', fn: myCustomFunction }
};
modalStore.trigger(d);

You can retrieve the data as follows. Note the wrapping #if conditional to prevent console errors on modal close.

html
{#if $modalStore[0]}
	<pre>{$modalStore[0].meta?.foo}</pre>
{/if}

SvelteKit SSR Warning

Be aware that there are known issues when using Svelte stores with SSR, such as our modal store. To prevent these issues please avoid the use of the modal store within any SvelteKit Load function. Likewise, if you need a modal to open on route initilization we advise triggering the open() method after the SvelteKit Browser environment context is available.

typescript
import { browser } from '$app/environment';

if (browser) modalStore.trigger({...});

For additional context please see this thread.