Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<svelte:element> proposal implementation #3928

Open
wants to merge 2 commits into
base: master
from
Open

Conversation

@erzr
Copy link

erzr commented Nov 15, 2019

An implementation of the proposal described in #2324.

Problem:
There's currently no way to dynamically specify a tag for an element. This is problematic if you want the ability to add a tag prop to a component and have some or all of that component be wrapped in the tag specified. Workarounds for this issue result in large, incomplete wrapper components such as https://github.com/erzr/jss-svelte/blob/master/packages/jss-svelte/src/components/TagWrapper.svelte that just cover the most commonly used tags.

Solution:
A new element named svelte:element has been implemented that accepts a single prop tag, which could be a string or variable containing the tag name.

Usage:
<svelte:element tag="h1">This is an h1</svelte:element>

@erzr erzr mentioned this pull request Nov 16, 2019
@antony

This comment has been minimized.

Copy link
Member

antony commented Nov 25, 2019

@erzr I can't comment on the proposal itself as I've never had need for this, but this PR could definitely use some tests.

Edit: I'm beginning to understand what this is about, and if it is accepted, I think we could re-use the existing

<svelte:component tag="blah" this={YourComponent} />

rather than creating a slightly confusing new <svelte:element> tag.

@erzr

This comment has been minimized.

Copy link
Author

erzr commented Nov 25, 2019

@antony Thanks for the feedback. Definitely do not disagree with the tests feedback. I didn't spend any time writing them because I was unsure if those proposal was something that Svelte was interested in as a whole.

I did consider re-purposing <svelte:component/> and I also did consider <svelte:options/> but ultimately settled on creating a new tag because I felt it aligned more closely with the Element internally:

https://github.com/sveltejs/svelte/blob/ea66d52f2b1718a77d0457a4ba77438291cb9f00/src/compiler/compile/nodes/Element.ts

vs

https://github.com/sveltejs/svelte/blob/ea66d52f2b1718a77d0457a4ba77438291cb9f00/src/compiler/compile/nodes/InlineComponent.ts

Considering <svelte:element/> internally as an Element would allow all of the existing logic that is applied to any other regular element to also be applied to this new tag. For example, any tag specific warnings:

if (!a11y_required_content.has(this.name)) return;
if (this.children.length === 0) {
this.component.warn(this, {
code: `a11y-missing-content`,
message: `A11y: <${this.name}> element should have child content`
});
}

Open to suggestions here. If this gets positive feedback and has a chance of getting merged in, I'm happy to spend the time writing tests to cover the new functionality.

@pngwn

This comment has been minimized.

Copy link
Contributor

pngwn commented Nov 26, 2019

I haven't looked at the code yet but I agree that this should be its own special tag, I don't think it makes sense to use svelte:component here, they are quite different in terms of implementation and the difference in usage is distinct enough to warrant a new API in my opinion.

@matthewrobb

This comment has been minimized.

Copy link

matthewrobb commented Dec 8, 2019

I am curious if this is being looked at seriously or not. This is currently an issue I keep running into when trying to build highly general purpose UI Library style component sets. Even the simple case of wanting to create a component that could be any of a number of tags (a, button, input[type=button|submit]) requires quite a bit of boilerplate where this proposal would make it mostly very trivial.

If the concern is baking in special case code for things like setting attributes then possibly requiring a staticly declared list of possible tags's would suffice?

<!-- is="" being a compile time only prop supporting a static set of valid tag names -->
<svelte:element tag={'a'} is="a, button, input" />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants
You can’t perform that action at this time.