Static methods could be used to define alternative constructors. For example, a rich text editor component could define a from static method initialising the component data from an existing textarea:
export default {
data() {
value: ''
},
// The component constructor need to be provided to those methods.
staticMethods(Component) {
// Return a dict of static methods
// (or attach them directly)
return {
from(textarea) {
const value = textarea.value;
const parent = textarea.parentNode;
const target = document.createAttribute('span');
textarea.style.display = 'none';
parent.insertBefore(target, textarea);
const editor = new Component({target, data: {value}});
const sub = editor.on('destroy', function() {
textarea.style.display = 'initial';
textarea.value = this.value;
parent.removeChild(target);
sub.cancel();
});
return editor;
}
};
}
};
It's easy enough to define those methods in an other module, but having those kind of methods defined with the component would be tidier.
This would be pretty simple to implement in a naive way - we could just keep that staticMethods method in the template object, and then just generate code to call
assign( component, template.staticMethods( component ) );
but I'm wondering whether there's some more static analysis we ought to be doing if we implemented this.
Can definitely see the value in being able to declare static methods (and properties). Can also see why it makes sense to implement as a function, since new this(...) feels like a weird thing to write.
Given that, what if it's a more general purpose setup hook, like this?
export default {
data() {
value: ''
},
// The component constructor need to be provided to those methods.
setup (Component) {
console.log( 'adding some static methods and properties' );
Component.from = function ( textarea ) {
// ...
};
Component.SOME_CONSTANT = 42;
}
};
In other words, Svelte makes no assumptions about whether the setup work involves declaring static methods, or overriding built-in methods for some esoteric debugging purposes or whatever — it's just a convenient place to do that work.
setup might not be the best name for it though... open to suggestions.
It does move us away from a world where the compiler can know almost everything about the component and how it can be used, into one where the behaviour becomes a black box. But as you point out, someone could do that anyway since it's just a regular JS constructor, they'd just be doing it in an even less predictable (to the compiler) way.
@Rich-Harris what about static methods and properties in v3?
You can do this in v3 by using the context="module" script.
<script context="module">
export const toUpper = str => str.toUpperCase();
</script>
This function can then be imported and used from anywhere:
import { toUpper } from './Component.svelte';
const myStr = toUpper('hi');
See the context="module" documentation or the Sharing Code section of the tutorial for more information.
@pngwn Thanks! But your reply about named export, not about static methods or properties. It is different things. For example static methods/properties are more convenient in some cases, when you need more coherence between a class and meta-data when this bunch traveling through a program.
For example:
<script>
export let Item;
</script>
{#if Item.TYPE === 1}
<svelte:component this={Item} foo bar={32} />
{:else}
<div class="wrapper">
<svelte:component this={Item} />
</div>
{/if}
Yes, I can pass a object with TYPE and Item, but it is hack. Isn't it?
<script>
export let obj;
</script>
{#if obj.TYPE === 1}
<svelte:component this={obj.Item} foo bar={32} />
{:else}
<div class="wrapper">
<svelte:component this={obj.Item} />
</div>
{/if}
Come to one of the support channels (Stack Overflow or Discord Chat) and we can help you with this. Github isn't the place for support questions.
Most helpful comment
Can definitely see the value in being able to declare static methods (and properties). Can also see why it makes sense to implement as a function, since
new this(...)feels like a weird thing to write.Given that, what if it's a more general purpose setup hook, like this?
In other words, Svelte makes no assumptions about whether the setup work involves declaring static methods, or overriding built-in methods for some esoteric debugging purposes or whatever — it's just a convenient place to do that work.
setupmight not be the best name for it though... open to suggestions.It does move us away from a world where the compiler can know almost everything about the component and how it can be used, into one where the behaviour becomes a black box. But as you point out, someone could do that anyway since it's just a regular JS constructor, they'd just be doing it in an even less predictable (to the compiler) way.