flekschas / svelte-simple-modal

A simple, small, and content-agnostic modal for Svelte v3 and v4
https://svelte.dev/repl/b95ce66b0ef34064a34afc5c0249f313
MIT License
422 stars 31 forks source link

Unable to dynamically populate modal content #90

Closed ajmeese7 closed 1 year ago

ajmeese7 commented 1 year ago

In my Modal.svelte file I have the following:

<script>
    // @ts-nocheck
    import Modal from "svelte-simple-modal";
    import { modalState } from "$lib/stores";

    const imports = {
        Person: () => import("./modals/Person.svelte")
    };
</script>

<Modal>
    {#if $modalState.open}
        {#await imports[$modalState.type]() then module}
            <svelte:component this={module.default} />
        {/await}
    {/if}
</Modal>

And in my stores.js I have the following:

import { writable } from "svelte/store";

export const modalState = writable({
    open: true,
    type: "Person",
});

This renders the contents of the passed modalState.type perfectly, but the content isn't nested in the Modal element whatsoever. There is no popup, no close button, and no greyed-out background.

Could you give me some guidance on how to accomplish what I am currently doing while having the generated content actually populate the Modal and be styled like such?

flekschas commented 1 year ago

Have you had a look at https://github.com/flekschas/svelte-simple-modal#usage-with-a-svelte-store or the related demo https://svelte.dev/repl/aec0c7d9f5084e7daa64f6d0c8ef0209?

ajmeese7 commented 1 year ago

@flekschas yes I have, it doesn't account for the dynamic import of components unfortunately. If you could provide a way to modify the demo to do so I would greatly appreciate it.

flekschas commented 1 year ago

If you have a demo like the one I posted above I am happy to take a look.

Have you tried something like this?

$: if ($modalState.open) {
  (async () => {
    const module = await import("./modals/Person.svelte");
    $modal.set(module.default)
  })()
}

The code you provided cannot work because you neither use open() from getContext('simple-modal') nor are you passing anything to <Modal />

ajmeese7 commented 1 year ago

I was able to adapt your recommendation to get it working fairly well:

<script>
  // @ts-nocheck
  import { writable } from "svelte/store";
  import Modal from "svelte-simple-modal";
  import { modalState } from "$lib/stores";

  const modal = writable(null);
  const imports = {
    Person: () => import("./modals/Person.svelte")
  };

  $: if ($modalState.open) {
    (async () => {
      const module = await imports[$modalState.type]();
      modal.set(module.default);
    })();
  }
</script>

<Modal show={$modal} />

Thanks for pointing me in the right direction! Closing this out now.