svelte-modals icon indicating copy to clipboard operation
svelte-modals copied to clipboard

Pass a modal with a slot to openModal()?

Open certainlyakey opened this issue 2 years ago • 4 comments

Hi! Thanks for a great package. I have an issue though with it that i can't resolve on my own apparently.

Currently all the examples cover providing a custom modal component with contents set via props (eg. title, message). In my modal component though, I have a <slot /> instead of a string-only message prop. The slot enables filling the body of the modal with some custom HTML.

The question is, is it possible to pass a modal with a slot when using openModal()?

What I'm doing is this:

<!-- Modal.svelte -->
<script lang="ts">
    import { closeModal } from 'svelte-modals';

    export let isOpen;
    export let title;
</script>

{#if isOpen}
    <div role="dialog">
      <h1 class="title">{title}</h1>
      <slot />
      <button on:click={closeModal}>Close</button>
    </div>
{/if}
<!-- App.svelte -->
<button on:click={openModal(Modal, { title:'Some title' })}>Open Modal</button>

It doesn't seem clear how to deal with it. There're no examples with using a custom modal with a slot. Does openModal() require a slotless modal component?

certainlyakey avatar Jun 23 '22 09:06 certainlyakey

Unfortunately slots are not supported as there's no way to express slot content in JS syntax (that I know of, at least). Only props can be passed in with openModal

mattjennings avatar Jun 23 '22 15:06 mattjennings

That's what I suspected, thanks. I hope once this gets fixed we get this feature in svelte-modals too.

certainlyakey avatar Jun 24 '22 10:06 certainlyakey

I am fairly new to svelte but wouldn't it be possible to have it work with the bind:this directive like this:

<script>
let myModal

function handleClick() {
  openModal(myModal)
}
</script>

<Modal bind:this={myModal}>
  <!-- Slot content goes here -->
</Modal>

So instead of receiving the Modal Component, the openModal function receives a Modal instance. Does that make any sense?

pomartel avatar Feb 02 '23 19:02 pomartel

I was thinking of putting the content in its own component rather than a slot, and passing the component as a prop:

<!-- Modal.svelte -->
<script lang="ts">
  import { closeModal } from 'svelte-modals'

  export let isOpen
  export let title
  export let component
</script>

{#if isOpen}
  <div role="dialog">
    <h1 class="title">{title}</h1>
    <svelte:component this={component} />
    <button on:click={closeModal}>Close</button>
  </div>
{/if}

The problem is that I want to have a form in the modal, and I'm not 100% sure of the best way to bind to the component's inputs if I do it this way…

unikitty37 avatar Apr 02 '23 13:04 unikitty37