mattjennings / svelte-modals

A simple, flexible, zero-dependency modal stack manager for Svelte.
https://svelte-modals.mattjennings.io
154 stars 8 forks source link

Pass a modal with a slot to openModal()? #15

Closed certainlyakey closed 1 week ago

certainlyakey commented 2 years ago

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?

mattjennings commented 2 years ago

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

certainlyakey commented 2 years ago

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

pomartel commented 1 year ago

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?

unikitty37 commented 1 year ago

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…

mattjennings commented 1 week ago

now possible with Svelte 5 snippets in v2.0.0