Modals

Use the modal component to show interactive dialogs and notifications to your website users available in multiple sizes, colors, and styles

The modal component can be used as an interactive dialog on top of the main content area of the website to show notifications and gather information using form elements from your website users.

Get started with multiple sizes, colors, and styles built with the utility classes from Tailwind CSS and the components from Flowbite.

Setup

<script>
  import { Modal } from 'flowbite-svelte'
</script>

Default modal

Modal visibility (open/close) is controlled by the open property. You can bind it to a variable that other element (usually button) will toggle. You can also use the open=true attribute to show open the modal by default.

Any <button> element put in the modal will close it on click. To prevent that behaviour set autoclose=false property.

Opening and closeing the modal will trigger the show and hide events.

  <script>
    let defaultModal;
  </script>

  <Button on:click={() => (defaultModal = true)}>Default modal</Button>
	<Modal title="Terms of Service" bind:open={defaultModal}>
    <p class="text-base leading-relaxed text-gray-500 dark:text-gray-400"> With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.</p>
    <p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.</p>
    <svelte:fragment slot='footer'>
      <Button>I accept</Button>
      <Button color="alternative">Decline</Button>
    </svelte:fragment>
  </Modal>

Pop-up modal

You can use this modal example to show a pop-up decision dialog to your users especially when deleting an item and making sure if the user really wants to do that by double confirming.

Notice lack of the footer slot.

<script>
  let popupModal;
</script>

<Button on:click={() => popupModal = true}>Pop-up modal</Button>
<Modal bind:open={popupModal}>
  <div class="text-center">
      <svg aria-hidden="true" class="mx-auto mb-4 w-14 h-14 text-gray-400 dark:text-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
      <h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">Are you sure you want to delete this product?</h3>
      <Button color="red" class="mr-2">Yes, I'm sure</Button>
      <Button color='alternative'>No, cancel</Button>
  </div>
</Modal>

Form element

Use this modal example with form input element to receive information from your users with the advantage of not having to link to another page but keeping the user on the currently active page. A great example would be a login or a register form.

<script>
  let formModal = false
</script>

<Button on:click={() => formModal = true}>Form modal</Button>
<Modal bind:open={formModal} size="xs">
	<form class="flex flex-col space-y-6" action="/">
		<h3 class="text-xl font-medium text-gray-900 dark:text-white p-0">Sign in to our platform</h3>
		<Label class="space-y-2">
			<span>Email</span>
			<Input type="email" name="email" placeholder="name@company.com" required />
		</Label>
		<Label class="space-y-2">
			<span>Your password</span>
			<Input type="password" name="password" placeholder="•••••" required />
		</Label>
		<div class="flex items-start">
			<Checkbox>Remember me</Checkbox>
			<a href="/" class="ml-auto text-sm text-blue-700 hover:underline dark:text-blue-500">Lost password?</a>
		</div>
		<Button type="submit" class="w-full1">Login to your account</Button>
		<div class="text-sm font-medium text-gray-500 dark:text-gray-300">
			Not registered? <a href="/" class="text-blue-700 hover:underline dark:text-blue-500">Create account</a>
		</div>
	</form>
</Modal>

Crypto wallet

Use this web3 modal component to show crypto wallet connection options like MetaMask or WalletConnect when building a website based on NFT authentication and collectibles.

<script>
  let walletModal = false
  import Metamask from "./Metamask.svelte"
  import Coinbase from "./Coinbase.svelte"
  import Fortmatic from "./Fortmatic.svelte"
  import OperaWallet from "./OperaWallet.svelte"
  import WalletConnect from "./WalletConnect.svelte"
</script>

<Button on:click={() => walletModal = true}>Crypto wallet modal</Button>
<Modal title="Connect wallet"  bind:open={walletModal} size="xs" padding="xs">
  <p class="text-sm font-normal text-gray-500 dark:text-gray-400">Connect with one of our available wallet providers or create a new one.</p>
  <ul class="my-4 space-y-3">
    <li>
        <a href="/" class="flex items-center p-3 text-base font-bold text-gray-900 bg-gray-50 rounded-lg hover:bg-gray-100 group hover:shadow dark:bg-gray-600 dark:hover:bg-gray-500 dark:text-white">
            <Metamask />
            <span class="flex-1 ml-3 whitespace-nowrap">MetaMask</span>
            <span class="inline-flex items-center justify-center px-2 py-0.5 ml-3 text-xs font-medium text-gray-500 bg-gray-200 rounded dark:bg-gray-700 dark:text-gray-400">Popular</span>
        </a>
    </li>
    <li>
        <a href="/" class="flex items-center p-3 text-base font-bold text-gray-900 bg-gray-50 rounded-lg hover:bg-gray-100 group hover:shadow dark:bg-gray-600 dark:hover:bg-gray-500 dark:text-white">
            <Coinbase />
            <span class="flex-1 ml-3 whitespace-nowrap">Coinbase Wallet</span>
        </a>
    </li>
    <li>
        <a href="/" class="flex items-center p-3 text-base font-bold text-gray-900 bg-gray-50 rounded-lg hover:bg-gray-100 group hover:shadow dark:bg-gray-600 dark:hover:bg-gray-500 dark:text-white">
            <OperaWallet />
            <span class="flex-1 ml-3 whitespace-nowrap">Opera Wallet</span>
        </a>
    </li>
    <li>
        <a href="/" class="flex items-center p-3 text-base font-bold text-gray-900 bg-gray-50 rounded-lg hover:bg-gray-100 group hover:shadow dark:bg-gray-600 dark:hover:bg-gray-500 dark:text-white">
            <WalletConnect />
            <span class="flex-1 ml-3 whitespace-nowrap">WalletConnect</span>
        </a>
    </li>
    <li>
        <a href="/" class="flex items-center p-3 text-base font-bold text-gray-900 bg-gray-50 rounded-lg hover:bg-gray-100 group hover:shadow dark:bg-gray-600 dark:hover:bg-gray-500 dark:text-white">
            <Fortmatic />
            <span class="flex-1 ml-3 whitespace-nowrap">Fortmatic</span>
        </a>
    </li>
  </ul>
  <div>
      <a href="/" class="inline-flex items-center text-xs font-normal text-gray-500 hover:underline dark:text-gray-400">
          <QuestionMarkCircle size=14 class="mr-2"/>Why do I need to connect with my wallet?</a>
  </div>
</Modal>

Sizes

You can use five different modal sizing options starting from extra small to extra large, but keep in mind that the width of these modals will remain the same when browsing on smaller devices.

<script>
  let sizeModal = false
</script>

  <Button size="xs" on:click={()=> {size = 'xs'; open = true} }>xs</Button>
  <Button size="sm" on:click={()=> {size = 'sm'; open = true} }>sm</Button>
  <Button size="md" on:click={()=> {size = 'md'; open = true} }>md</Button>
  <Button size="lg" on:click={()=> {size = 'lg'; open = true} }>lg</Button>
  <Button size="xl" on:click={()=> {size = 'xl'; open = true} }>xl</Button>

  <Modal title="Terms of Service" bind:open={sizesModal} {size}>
    <p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.</p>
    <p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.</p>
    <svelte:fragment slot='footer'>
      <Button>I accept</Button>
      <Button color="alternative">Decline</Button>
    </svelte:fragment>
  </Modal>

Placement

<script>
  let placementModal = false
  const setPlacement = (value) => () => {
    placement = value;
    open = true
  };
</script>

<div class="inline-grid grid-cols-3 grid-rows-3 gap-4">
  <Button on:click={setPlacement('top-left')}>top-left</Button>
  <Button on:click={setPlacement('top-center')}>top-center</Button>
  <Button on:click={setPlacement('top-right')}>top-right</Button>
  <Button on:click={setPlacement('center-left')}>center-left</Button>
  <Button on:click={setPlacement('center')}>center</Button>
  <Button on:click={setPlacement('center-right')}>center-right</Button>
  <Button on:click={setPlacement('bottom-left')}>bottom-left</Button>
  <Button on:click={setPlacement('bottom-center')}>bottom-center</Button>
  <Button on:click={setPlacement('bottom-right')}>bottom-right</Button>
</div>

<Modal title="Terms of Service" bind:open={placementModal} {placement}>
  <p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.</p>
  <p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.</p>
  <svelte:fragment slot='footer'>
    <Button>I accept</Button>
    <Button color="alternative">Decline</Button>
  </svelte:fragment>
</Modal>

Props

The component has the following props, type, and default values. See types page for type information.

Modal

Name Type Default
open boolean false
title string undefined
size 'xs' | 'sm' | 'md' | 'lg' | 'xl' 'md'
placement | 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' 'center'
autoclose boolean true
backdropClasses string 'bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40'

References