Giter Site home page Giter Site logo

Allow for . in attribute names about jsx HOT 15 OPEN

facebook avatar facebook commented on May 5, 2024 1
Allow for . in attribute names

from jsx.

Comments (15)

Alxandr avatar Alxandr commented on May 5, 2024 2

None of those are problematic. If you read my transformation, it should be like this:

React.createElement("tag-name", { "some": {a: 1}, "some.b": "2"});
React.createElement("tag-name", { "some.a": "1", "some": {b}});
React.createElement("tag-name", { "some": "1", "some.b": "2"});

from jsx.

Alxandr avatar Alxandr commented on May 5, 2024 1

@NekR I'd argue that those are fairly different though. One is an attribute, the other is an element name. Though, I've already stated my opinion. So I'll let the rest discuss.

from jsx.

RReverser avatar RReverser commented on May 5, 2024

What should

<tag-name some={{ a: 1 }} some.b=2 />

and

<tag-name some.a=1 some={{ b: 2 }} />

and

<tag-name some="1" some.b="2" />

do?

It brings too much questions, conflicts and undefined behavior IMO.

from jsx.

Alxandr avatar Alxandr commented on May 5, 2024

Let me clarify some more. This are not object expressions/merging. It's just treating the entire attribute (dots and all) as a string. So you can't do attrs.some.a, you'll have to do attrs['some.a'].

from jsx.

sebmck avatar sebmck commented on May 5, 2024

I don't think @RReverser was talking about the syntactic ambiguity rather that in JavaScript a . is used to represent property access and the use of it as a key is very confusing.

from jsx.

Alxandr avatar Alxandr commented on May 5, 2024

@sebmck well, he said "conflicts and undefined behavior". Of which there are none.

from jsx.

NekR avatar NekR commented on May 5, 2024

@Alxandr why underscore (_) does not work for you?

<div test_foo_bar="123"></div>

https://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=%3Cdiv%20test_foo_bar%3D%22123%22%3E%3C%2Fdiv%3E

from jsx.

Alxandr avatar Alxandr commented on May 5, 2024

@NekR it's not at all that it doesn't work. It's that I have a HTML element that expects an attribute with . in it's name.

from jsx.

NekR avatar NekR commented on May 5, 2024

@Alxandr Hmm.. interestingly, why?

from jsx.

Alxandr avatar Alxandr commented on May 5, 2024

@NekR No particular reason. It was made that reason a good while ago. It's a custom element, and I've been using it for a while. Now, I could obviously change it, which is probably what I'll end up having to do (as opposed of today, where I customly do element.setAttribute). I just thought JSX should support this, mostly given that I figured it would be easy to implement, and not cause any issues with existing code. And HTML supports it.

from jsx.

NekR avatar NekR commented on May 5, 2024

@Alxandr yes, good reason. But there might be a problem with current <foo.Bar> which in supported implementations means foo.Bar() (or create(foo.Bar)) and if <div foo.bar=""> will translate just to {'foo.bar': ''} it may cause some confusions. Anyway, at some point I also thought that JSX should support it was confused that it don't. Interestingly what other people think here.

from jsx.

treshugart avatar treshugart commented on May 5, 2024

Big +1 to this. I think the question worth asking is: is there benefit in not conforming to the HTML spec? And if so, does it outweigh the benefits that consumers get by having that predictability?

from jsx.

amiller-gh avatar amiller-gh commented on May 5, 2024

Hey all, opening this old discussion back up! Just had a major use case come up in a new project that this language feature would be great syntactic sugar for.

Side note: while looking into this language feature, I found an inconsistency between the JSX spec and Babylon's implementation that more work on this issue may help resolve, but should probably be fixed regardless (excuse me for the length of this comment!)

The JSX parser in Babylon currently allows namespaced tag names with member expressions:

<test:foo.bar></test:foo.bar>

However, this is wrong according to the current JSX spec, where JSXNamespacedNames do not allow member expressions, only identifiers:

JSXElementName :
- JSXIdentifier
- JSXNamespacedName
- JSXMemberExpression

JSXAttributeName :
- JSXIdentifier
- JSXNamespacedName

JSXIdentifier :
- IdentifierStart
- JSXIdentifier IdentifierPart
- JSXIdentifier NO WHITESPACE OR COMMENT `-`

JSXNamespacedName :
- JSXIdentifier `:` JSXIdentifier

JSXMemberExpression :
- JSXIdentifier `.` JSXIdentifier
- JSXMemberExpression `.` JSXIdentifier

This grammar allows tag names like these:

<foo:bar></foo:bar>
<foo.bar></foo.bar>

But does not allow for namespaced member expression tags like the Babylon parser currently does:

<test:foo.bar></test:foo.bar>

By updating the definition of JSXNamespacedName to:

JSXNamespacedName :
- JSXIdentifier : JSXIdentifier
- JSXIdentifier : JSXMemberExpression
- JSXMemberExpression : JSXIdentifier
- JSXMemberExpression : JSXMemberExpression

The spec will match what Babylon currently parses as valid JSX, and will have the fringe benefit of enabling namespaced, member expression attributes:

<div attr:biz.baz="value"></div>

One more small update to JSXAttributeName and we get support for un-namespaced attribute names that @Alxandr asked for.

JSXAttributeName :
- JSXIdentifier
- JSXMemberExpression
- JSXNamespacedName

However, none of the above addresses @RReverser and @NekR's concern about behavior ambiguity. One option that addresses both use cases is to mirror the behavior used by tag names, and preserve the use of member expressions as data accessors, where:

let tagNames = { div: 'div' };
let attrsNames = { custom: "some.value" };
<tagNames.div attrsNames.custom="value" />;

may be transformed to

let tagNames = { div: 'div' };
let attrsNames = { custom: "some.value" };
React.createElement(tagNames.div, { [attrsNames.custom]: "value" });

My use case: a library that exports attribute names for use on elements that may change between dev and production builds and should be applied dynamically, but where you want to apply them in a cleaner, more statically analyzable way than with spread attributes:

import lib from "my-library";
return ( <div lib.customProp="value" ></div> );

I think theres value in adding this language feature, and I'm happy to help make updates to assorted parsers / transpilers to support it if the proposal moves forward – the example Babylon implementation I've been playing with is here:
amiller-gh/babylon@de84728

from jsx.

syranide avatar syranide commented on May 5, 2024

My use case: a library that exports attribute names for use on elements that may change between dev and production builds and should be applied dynamically, but where you want to apply them in a cleaner, more statically analyzable way than with spread attributes:

return ( <div [lib.customProp]="value" ></div> ); is the answer to that (computed property names). Although I have no idea why changing attribute names between dev and prod is a good idea.

from jsx.

amiller-gh avatar amiller-gh commented on May 5, 2024

Ah well look at that, I just re-created an existing proposal! Thanks for calling it out @syranide. Should this issue be closed in favor of #21?

from jsx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.