Tried creating a web component/custom element that would wrap a table from tabulatorjs using svelte, but for some reason can't get the table to properly display. I've followed the docs text and it seems to work works when you're running normal svelte components, but fails as a custom element/component.failing web component
VS
For code examples, here's a demo repo containing "main" branch which works and "broken" branch which doesn't. Also worth noting the counter web component works in both branches, but tabulator fails.
Alright, first of all thanks for setting up the repo it really helped with figuring it out! You problem is that you're importing the tabulator.min.css file with svelte:head, which doesn't work because of what the documentation explains:
Styles are encapsulated, rather than merely scoped (unless you set shadow: "none"). This means that any non-component styles (such as you might have in a global.css file) will not apply to the custom element, including styles with the :global(...) modifier
If you unminify it and put it inside the style tag you'll basically have a bunch of unused-css-selector
warnings that be purged when you build. So the solution is to wrap every single selector with the :global
tag so the compiler will let all the style pass through to the dist/assets/main.js
where it will encapsulate the table with the appropriate styles. You'll end up with this monstruosity but that works when built — don't forget to add the
<svelte:options customElement="custom-table"/>
to the beggining (I removed cause it confuses the REPL). Now, another approach to avoid wrapping every single selector is installing svelte-preprocess
and simply opening your style tag like this:
<style global>
/*whole unminified tabulator.min.css*/
</style>
Set it up on your svelte.config.js
, which brings me to the last point: When I set up the project Svelte kept complaining about setting customElement: true
in the compiler options, which I saw you did inside the vite.config.js
' svelte plugin. But the only way Svelte stopped complaining about it was setting it directly in the svelte config, which comes out like this
//svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
import { sveltePreprocess } from 'svelte-preprocess' // optional
export default {
// moved from vite.config.js
compilerOptions: {
customElement: true,
},
preprocess: vitePreprocess(), // default preprocess
preprocess: sveltePreprocess(), // if you want to use Svelte the global style attribute
}
Then you just build it and it works!