Modal

Modals are used to display content in a layer above the application.

# Features

  • Focus is moved and contained within the modal while it is open, and returned to the trigger element when it is closed.
  • Manages screen reader announcements for improved accessibility.
  • Modal can be closed by interacting outside of it or pressing theEscape key.

# Dependencies

This module depends on focus-trap.

# Anatomy

Typically, a modal consists of:

  • Trigger: The element that opens the modal.
  • Modal: The container element that consists of:
    • Title: An optional element used as title of the modal.
<script>
	import { createModal } from '@grail-ui/svelte';

	const { useModal, modalAttrs, titleAttrs, triggerAttrs, open } = createModal();
</script>

<button {...$triggerAttrs} on:click={() => ($open = true)}>Open</button>

{#if $open}
	<div use:useModal {...$modalAttrs}>
		<h3 {...$titleAttrs}>Title</h3>
		<div>
			Content
		</div>
	</div>
{/if}

# Examples

# Custom portal container

If you want to customize the element that your modal portals into use the portal and pass the actual element or a CSS selector.

createModal({
portal: '#custom',
})

# Accessibility

Adheres to the Dialog WAI-ARIA design pattern.

# Keyboard Interactions

Key description
Esc
Closes the modal and moves focus to trigger element.
Tab
Moves focus to the next focusable element.
Shift + Tab
Moves focus to the previous focusable element.

# API

# ModalConfig

Property Description Default
open?
boolean
The open state of the dialog when it is initially rendered.
true
portal?
string | HTMLElement | null
Where to "portal" the modal element outside it's initial DOM position. It can be a HTMLElement or a CSS selector that points to an already existing element.
"body"
initialFocus?
HTMLElement | SVGElement | string | false | Function
Specify an element to receive focus when the dialog is opened. You can set this option to false (or to a function that returns false) to prevent any initial focus.
onOpenChange?
(value: boolean) => void | undefined
Event handler called when the open state changes.
dismissible?
boolean
Whether to close the modal when the user interacts outside it.
false
keyboardDismissible?
boolean
Whether pressing the Escape key to close the modal should be disabled.
true
onInteractOutside?
(e?: PointerEvent) => void | boolean
Event handler called when a pointer event occurs outside the bounds of the dialog. Closing can be prevented by calling event.preventDefault() or by returning false.

# ModalReturn

Property Description
useModal
Action<HTMLElement, void>
Action for the container element.
open
Writable<boolean>
The controlled open state of the modal.
modalAttrs
Readable<Record<string, string>>
HTML attributes for the content element.
titleAttrs
Readable<Record<string, string>>
HTML attributes for the title element.
triggerAttrs
Readable<Record<string, string>>
HTML attributes for the trigger element.
dismissible
Writable<boolean>
The controlled state of the dismissible property.
keyboardDismissible
Writable<boolean>
The controlled state of the keyboardDismissible property.