One of the biggest disadvantages with Svelte is the lack of component libraries.
There are a few attempts, but none are actually finished. I think one of the reasons for that is how cumbersome it is to create Microcomponents like Buttons with just custom styles or other minor expansions.
Even if you ignore creating such a Component library, usage would be cumbersome as well:
you'd need to import every little Component seperately, in a seperate line. Components heavily reliant on, say bootstrap-based Components, would quickly look like this at the top:
<script>
import Button from 'svelte-bs/Button.svelte'
import Card from 'svelte-bs/Card.svelte'
import Nav from 'svelte-bs/Nav.svelte'
import Input from 'svelte-bs/Input.svelte'
import Form from 'svelte-bs/Form.svelte'
...
</script>
I Propose a feature I'd call "Component Collections":
A way of bundling components in a way they can be 'bulk-imported' like this:
import { Button, Card, Nav, Input, Form } from 'svelte-bs'
There would be many different possible approaches to implementing the creation of such component-collections, differing mainly in how much new stuff would have to be added to svelte.
You could make Folders containing .svelte files the source for these components. So if you have a folder svelte-bs/components containing Button.svelte, Card.svelte and so on you could import them with
import { Button, Card } from 'svelte-bs/components/*'
I actually like this idea from a standpoint of elegance, altough it could get confusing and could inhibit good filestructure internally, so its not ideal
.sveltecollection filesanother alternative would be to add a seperate file-format called .sveltecollection that could contain information about the collection.
Because there is no meaningful paralell to this in plain javascript or html, this would mean either adding custom syntax to svelte or abusing javascript exports in some way. It would mean expanding svelte's syntax quite a bit, and, whilst being the most flexible approach, I think this is not the best idea
If svelte components could be Imported into javascript, even if they cant be used in any meaningful way other than re-exporting them, it could allow for idiomatic use of the export default-syntax in a dedicated collection.js-file like this:
import Button from 'components/Button.svelte'
import Card from 'components/Card.svelte'
export default { Button, Card }
This would be the easiest to understand and the one that needs the least modification to the syntax, but i have no idea how hard this would be to implement into the compiler, as components arent really javascript-objects at all. This could be handled as some kind of reference to the actual components path, but it would still propably be the most complicated way of implementing component-collections.
.sveltecollection-approach.sveltecollection-files could also be regular .svelte files that can contain multiple components.
This would also make it less cumbersome to actually create microcomponents, because creating a new file for a 5-line component is rather anoying.
These files could use a special html-tag-syntax to seperate the components, resulting in a syntax similar to this:
<Component Button>
<script>
....
</script>
<button class="btn btn-primary" on:click={.....}><slot/></button>
</Component>
<Component Card>
.....
</Component>
An alternative approach would be to make this more of a templating-style feature and use
{#export Component Button} .....{/export} or something like that.
having this, you could then just
import { Button, Card } from 'svelte-bs/components.sveltecollection'
I think this would be the best solution, as it not only solves the problem of verbose imports in a rather simple way, but also makes developing microcomponents a bit better. You could also use this approach to allow re-exporting components, so you dont end up with 1000 line sveltecollection files just to collect all bootstrap components in one file.
I know however that the svelte-team has already said they propably wont include multi-component files, because it would introduce unnecessary complexity to svelte.
I Actually disagree with that, seeing that svelte is absolutely the easiest "framework" to get into, having multi-component files wouldn't noticably raise the complexity, as its a rather easy concept to grasp.
The pure appeal of 'it looks more like pure html this way' is more of a religious ideal than a practical wish, seeing that the javascript-syntax has been "abused" for things like $:.
Svelte being a compiler, it knows about all components you're using ahead of time.
Having component collections, this could be a huge advantage to sveltes brevity:
Smart wildcard imports
If you import components from a Component collection, the Svelte compiler could allow using
import * from 'svelte-bs'
to import all components provided by Svelte-bs, but then internally converting it to an import of only the used Components.
I'd say this feature isn't vital to how usable and beautiful svelte is, altough i'd say it could improve working with it very noticably.
Also, I'd say that it could encourage Library-authors to create Component-collections, specifically to wrap CSS-Frameworks like bootstrap and semantic-ui, and by that be a lot more appealing to people coming over from react.
Coming from react myself, the thing i miss the most is the semantic-ui-react library and the possibility to quickly create wrapper components for such things that are adaptable and reusable, without causing a lot of unnessecary verbosity.
While I absolutely don't see myself as able to implement something like that, I'd be more than happy to discuss about the design, the possibilities and problems with this feature-request!
Svelte already importable from js (please check your main.js file) So, you can just use index.js file with simple code such:
import Button from “./components/Button.svelte”;
import Card from “./components/Card.svelte”;
export {
Button,
Card
};
To build on that, you can then also already do:
<script>
import * as Collection from 'wherever';
</script>
<Collection.Button/>
Oh, didn't see that haha, I guess that was a lot of writing for nothing 😂 although I'd say that my approach to multiple components in one file is still relevant and should be something to discuss
But I'll still close this issue, as my main topic is kinda irrelevant haha
If someone comes across this, there is a more elegant solution if you make an index.js file at the root of your components folder:
export { default as Pill } from './Pill.svelte'
so then you can do
import { Pill } from 'wherever-that-index-file-is'
Most helpful comment
If someone comes across this, there is a more elegant solution if you make an index.js file at the root of your components folder:
export { default as Pill } from './Pill.svelte'so then you can do
import { Pill } from 'wherever-that-index-file-is'