Is your feature request related to a problem? Please describe.
Given the usage of the following hypothetical component:
<Icon data-tooltip="foobar" />
I receive a warning that data-tooltip has not been declared as a property on the Icon component. However, there is no way to do that since it is hyphenated.
Describe the solution you'd like
Inside my component, it would be nice if I could declare the property like this:
export let dataTooltip = null
Describe alternatives you've considered
I know that the properties are also available in $$props. But that doesn't really solve the problem.
const dataTooltip = $$props['data-tooltip']
While this would give me access to the value, it doesn't remove the in browser warning.
How important is this feature to you?
It's annoying. Important? Well, certainly not a deal killer. And for now I just am using the form: <Icon tooltip="foobar" />. And then I am passing the property to the hyphenated version inside the component.
The reason this came about was I was trying to just use a spread operator and pass props thru. But, here I cannot because I don't want to keep seeing those warnings all over the place.
A component's 'unknown prop' warning is _supposed_ to be suppressed if the component uses $$props at all (#2881). Is this not what you're seeing? Do you have a repro?
Thanks for the response. I believe that I was still getting it, but I'll go back and post a snippet when I get back to a computer.
In this specific case, the property looks like HTML5 user-defined data.
Maybe take hyphenated names and make the second word of the hyphen a key inside the first name?
Such as:
<Foo data-test="some data">
//... inside Foo
<script>
export let data;
</script>
{data.test}
True, but I am not sure that would be the only use case.
@dkondrad @ahopkins yeah I think this is a bad example. Ignoring data- prefixes, something as simple as:
<Profile avatarType="xxx">
where I'd really prefer to declare it as:
<Profile avatar-type="xxx">
@antony I agree. It just so happened that my example I was using something that required a data- property.
I agree with your example.
@ahopkins Did you ever get a reproduction for the 'unknown prop' warning persisting despite the component referencing $$props?
Of course I cannot recreate it now ...
myCredibility -= 1
As stated, as soon as $$props is referenced, the warning goes away. Perhaps I had this on an older build of svelte?
@Conduitry I am not sure that this was ready to be closed. The warning was sort of a side matter.
I think the issue (as displayed by @antony) is still a valid feature request. Unless you are saying this is not something that you would entertain?
Yeah, fair, we can re-open this.
This needs to be done before Rich comes along and does this:
<Profile avatar_type="xxx">
But seriously... not sure what the behaviour should be if we did this:
<Profile avatarType="xxx" avatar-type="xxx">
export let avatarType
I suppose we could consider avatar-type to be equivalent to avatarType and thus act as if the same prop had been declared twice, which is currently to throw an error saying "Attributes need to be unique (5:18)" - perhaps this message needs to say something like "Attributes need to be unique, excluding hyphens" or something far more meaningful than that.
Another weird edge case:
<Profile avatar--type="xxx">
I'd suggest that the above is left intact, thus ending up as the (un-addressable) prop avatar--type.
Not knowing the feasibility of this... I like that suggestion.
And what about when it's compiling to a custom element? When adopting Svelte, I tried to keep the hyphenated attribute names I'd previously had when writing CEs from scratch and couldn't figure it out in the time I had, so gave up. Do web components get access to $$props set via hyphenated attributes? I wasn't aware of $$props at all, so I didn't try it.
@morewry It looks like they don't. I just tried it.
I'd really like to see this feature implemented. Without it, it seems the only option is to pass in attributes as snake_case, which is inconsistent with the rest of the DOM elements. I can't even seem to get camelCase to work.
The solution was already outlined by Mr @Rich-Harris in #875, just make the camelCase to kebab-case translation possibility.
We are making transition from using polymer web components and upgrading our existing component library to use svelte web components where applicable. Inability to define hyphenated props is a blocker for us.
@osamamaruf I've faced this problem too.
As temporary solution I've written my own wrapper for CustomElement, where all camelCased attributes are converted to dash-case:
import MyCustomComponent from './MyCustomComponent.svelte';
class MyCustomComponentWrapper extends MyCustomComponent {
static get observedAttributes() {
return (super.observedAttributes || []).map(attr => attr.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase());
}
attributeChangedCallback(attrName, oldValue, newValue) {
attrName = attrName.replace(/-([a-z])/g, (_, up) => up.toUpperCase());
super.attributeChangedCallback(attrName, oldValue, newValue);
}
}
customElements.define('my-custom-component', MyCustomComponentWrapper);
MyCustomComponent.svelte
<script>
export let someDashProperty;
</script>
<svelte:options tag={null} />
{someDashProperty}
Then you can use it in this way:
<my-custom-component some-dash-property="hello"></my-custom-component>
Hope it helps until fix is coming
Just wanted to say +1 for automatically converting propLikeThis to attr-like-this.
I've been looking around for some "best practices" for publishing custom elements, and besides this article, I've also looked at the pattern used by the same author's chessboard-element, and it considers lowercase-kebab attributes to be equivalent to camel-cased props.
@oranmor's temporary solution works great in the meantime, though!
@oranmor do you have a "full" example? I don't understand how you implement the MyCustomComponent.
@benkeil in fact it is a full example.
You can see complete working repo here: https://github.com/oranmor/svelte-custom-element-dash-properties-example
Most helpful comment
@osamamaruf I've faced this problem too.
As temporary solution I've written my own wrapper for CustomElement, where all camelCased attributes are converted to dash-case:
MyCustomComponent.svelte
Then you can use it in this way:
Hope it helps until fix is coming