-
|
Hello, Recent svelte adopter (and so far mostly enjoyer), I'm trying to find a way to create svelte components from javascript code. Note that I'm using it in SPA mode, so I do not have access to The feature I'm trying to achieve, is on some user action (in this case a large file upload) create a card displaying progress Here a very simple case using pure html: <script lang="ts">
function btnClick(){
let card = document.createElement('div');
let cardcontent = document.createElement('p');
cardcontent.innerText = "Pending Action ...";
card.appendChild(cardcontent);
let cardbar = document.getElementById("mycards")!;
cardbar.appendChild(card);
}
</script>
<button type"button" onclick={btnClick()}>
click me
</button>
<div id="mycards"></div>In my case I'm using flowbite-svelte, so the idea would be to create a svelte component. Which doesn't work with Browsing the docs, using import { Card } from 'flowbite-svelte';
function btnClick(){
let cardbar = document.getElementById("mycards")!;
let new_card = mount(Card, {target: cardbar});
}It works for the card, but now it's not obvious to me how to set the content, I've tried a few things Idea 1:I thought about using mount all the way down. however it only accepts svelte components as input so elements created with Idea 2:Given my understanding on how svelte works. The content is actually a snippet labelled function btnClick(){
let cardbar = document.getElementById("mycards")!;
const content = `<p>Pending Action ...</p>`
const cardcontent = createRawSnippet(() => {
return {
render: () => content,
setup: (node) => {
$effect(() => {
node.textContent = content;
});
}
}}
);
let new_card = mount(Card, {
target: cardbar,
props: {
class: "action-card",
children: cardcontent,
},
})
}Which appears to be correct for my JS linters, but does not display the content inside the card. I'm not sure this Idea 3 (aka 0'):That card is just a Best, |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
|
It depends on what the content is and where it is supposed to come from. You can e.g. reference snippets defined in the markup and snippets that don't use local state can also be exported from the module script. That may be easier than working with One can also import components and pass those as props & add them in the receiving component's markup. Regarding the approach using Though if you create a wrapper, you could also add an element inside the card and expose that; this way you can add DOM elements directly to the component. <!-- CardWrapper.svelte -->
<script>
import Card from './Card.svelte';
const { ...rest } = $props();
let contents;
export { contents }
</script>
<Card {...rest}>
<div bind:this={contents}></div>
</Card><script>
import { mount } from 'svelte';
import CardWrapper from './CardWrapper.svelte';
let cards;
async function btnClick() {
const content = document.createElement('p');
content.textContent = 'Pending Action...';
const card = await mount(CardWrapper, {
target: cards,
props: { class: "action-card" },
});
card.contents.append(content);
}
</script>
<button onclick={btnClick}>Add</button>
<div bind:this={cards} ></div> |
Beta Was this translation helpful? Give feedback.
-
|
I think this could be accomplished much more idiomatically with an array. Basic exampleThe most basic example is simply iterating over the array and showing static content. With mutationsOnce the value is captured in state, it can be updated directly. You can update, add, or remove from the array to control what components are rendered. With custom componentsIf you also want dynamic components for each upload, you could capture that in the array. |
Beta Was this translation helpful? Give feedback.
It depends on what the content is and where it is supposed to come from. You can e.g. reference snippets defined in the markup and snippets that don't use local state can also be exported from the module script. That may be easier than working with
createRawSnippetwhich is not really meant for general use.One can also import components and pass those as props & add them in the receiving component's markup.
Regarding the approach using
createRawSnippet, that works if theCardactually renderschildren.If that is not the case, the library may still be using
<slot />.You could create a wrapper component as a workaround (so you have
<Card {...rest}>{@render children()}</Card>).Though if …