Modal

The Modal component shows content in an overlay above the page, with focus trapped inside it and the page behind it locked from scrolling.

About

Escape closes the topmost modal only, so stacked modals close one at a time. The size, the animation and the backdrop are props, and you can drive the whole thing from your own state with bind:open instead of passing a trigger.

Example

To use the Modal component, you need to import it into your Svelte file. This setup allows you to easily integrate the Modal component into your project.

Svelte
<script>
  import { Modal } from "theui-svelte";
</script>

<Modal label="Modal Button">
  Hello Modal!
</Modal>

Positioning

The position prop in the Modal component determines where the modal is displayed vertically on the screen. It can be set to 'top', 'center', or 'bottom', with the default being 'center'. This allows you to align the modal according to your design needs, whether you want it at the top for quick alerts, in the center for standard dialogs, or at the bottom for additional content.

Svelte
<!-- Top-aligned Modal -->
<Modal position="top"> ... </Modal>

<!-- Centered Modal (Default) -->
<Modal position="center"> ... </Modal>

<!-- Bottom-aligned Modal -->
<Modal position="bottom"> ... </Modal>

Sizing

The size prop controls the width of the Modal. Options include 'sm' for small, 'md' for medium (default), 'lg' for large, and 'full' for full-screen. This allows you to adjust the modal size based on your content needs.

Svelte
<!-- Small Modal -->
<Modal size="sm"> ... </Modal>

<!-- Medium-sized Modal (default) -->
<Modal size="md"> ... </Modal>

<!-- Large Modal -->
<Modal size="lg"> ... </Modal>

<!-- Full-width Modal -->
<Modal size="full"> ... </Modal>

Animation

Animation Type

The animation prop defines the type of animation used when the Modal opens or closes. Available options include 'slide-down', 'slide-up', 'fade', 'zoom-in', and 'zoom-out'. Each option provides a different visual effect for how the Modal appears or disappears.

Svelte
<!-- Modal with slide-down animation -->
<Modal animation="slide-down"> ... </Modal>

<!-- Modal with slide-up animation -->
<Modal animation="slide-up"> ... </Modal>

<!-- Modal with fade (default) animation -->
<Modal animation="fade"> ... </Modal>

<!-- Modal with zoom-in animation -->
<Modal animation="zoom-in"> ... </Modal>

<!-- Modal with zoom-out animation -->
<Modal animation="zoom-out"> ... </Modal>

Animation Speed

The animationSpeed prop controls the speed of the Modal's animation. It accepts the following values: 'none', 'slower', 'slow', 'normal', 'fast', and 'faster'. The default is 'fast'. Setting this prop to 'none' will disable the animation, while the other values adjust the animation speed accordingly.

Svelte
<Modal animationSpeed="slower"> ... </Modal>
<Modal animationSpeed="slow"> ... </Modal>
<Modal animationSpeed="normal"> ... </Modal>
<Modal animationSpeed="fast"> ... </Modal>
<Modal animationSpeed="faster"> ... </Modal>
<Modal animationSpeed="none"> ... </Modal>

Disable Close Button

The closeButton prop allows you to control the visibility of the close button in the Modal. By default, the close button is visible (true). Set this prop to false to hide the close button. You can also pass a string of custom classes to style the close button.

Svelte
<Modal closeButton={false}> ... </Modal>

Customization

To create a custom-styled modal, you can use the following props to apply custom classes to the modal's header, body, footer, and outer container:

  • headerClasses: Customize the header section of the modal.
  • bodyClasses: Customize the body section of the modal.
  • footerClasses: Customize the footer section of the modal.
  • containerClasses: Customize the outer container of the modal.
  • buttonClasses: Customize the modal trigger created by the label prop.

These props allow you to apply your own styles or use TailwindCSS classes to control the layout and appearance of different parts of the modal.

Svelte
<Modal
  bodyClasses="bg-blue-100 dark:bg-blue-950 text-blue-800 dark:text-blue-300 border-blue-500/50 border-4 py-8"
  headerClasses="bg-blue-400/50 text-blue-600 dark:text-blue-100 shadow-blue-500/50 rounded-md p-4 border-0 shadow-md text-lg font-bold"
  footerClasses="border-blue-300/50 border rounded-xl p-2"
>
  {#snippet label()}
    <Button>Modal Button</Button>
  {/snippet}

  {#snippet header()}
    <h4>Custom Modal Header</h4>
  {/snippet}

  .....

  {#snippet footer()}
    <Button class="bg-warning-500 hover:bg-warning-600 text-warning-900" size="sm">Close</Button>
  {/snippet}
</Modal>

Accessibility

The Modal carries the ARIA attributes it needs and answers to the keyboard out of the box.

  1. ARIA Attributes: The Modal uses role="dialog" and aria-modal="true" to indicate its purpose to assistive technologies. aria-labelledby and aria-describedby are added automatically to associate the header and content with the Modal. If the Modal has no header, it is labelled by the ariaLabel prop instead, which also labels a custom label snippet trigger.
  2. Keyboard Navigation
    • Focus is automatically moved to the Modal when it opens.
    • Users can navigate through focusable elements using the tab key.
    • Pressing the Esc key closes the Modal. When modals are stacked, only the topmost one closes.
    • A custom label snippet trigger can be activated with the Enter or Space key.
  3. Focus Management: focus is trapped inside the Modal while it is open, so nothing behind it can be reached. On close, focus returns to the element that opened it. Page scrolling is locked while the Modal is open, and the closed Modal is marked inert.
  4. Screen Reader Announcements: The Modal is announced as a dialog to screen readers, helping users understand its purpose.
  5. Color Contrast: Ensure that text and background colors inside the Modal meet WCAG contrast ratio standards .

Configuration