vuejs / babel-plugin-jsx

JSX for Vue 3
https://vue-jsx-explorer.netlify.app
MIT License
1.71k stars 142 forks source link

Issue with using className instead of just class #157

Open oliverfindl opened 3 years ago

oliverfindl commented 3 years ago

Hello team,

I am currently developing new library that would output JSX template, so this output could be used in Vue and React projects.

Unfortunately, I found this library does not adhere DOM API same way as React do. My issue is caused by using className instead of just class, because I am using object destructing I cannot use class keyword. Same situation would happen by using htmlFor instead of just for. Both class and for are reserved keywords and cannot be used in object destructing.

So I want to ask, if there is possibility to introduce new option to convert those two attributes.

Thanks

skyrpex commented 3 years ago

Just in case you didn't know, you can rename them while destructuring:

const { for: htmlFor, class: classNames } = {
    for() {},
    class() {},
};
oliverfindl commented 3 years ago

Hello,

sure I am familiar with object deconstructing syntax. But my main issue is, that I have library, which is already outputting JSX template (using className instead of class) and wanted to write Vue wrapper for it. If I rename className to just class there, it would break in React instead. My current JSX template implementation in that library looks like this (simplified):

class Library {

    constructor(options) {
        // ...
    }

    // ...

    get attributes() {
        // ...
        return {
            // ...
        };
    }

    // ...

    get template() {
        const { attributes } = this;
        return <div ...attributes>...</div>;
    }

}

Note that this is not in Vue (or React) component, but it is only getter from my library, that should be used in Vue/React component as template. Basic usage in Vue/React would be as instance (which is reactive) and each mutation of its state would change my JSX template output that would be directly mapped into component.

Sure I can copy whole template getter from my library to Vue component and use it like this:

// ...
render() {
    const { attributes } = this;
    if(attributes.className) {
        attributes.class = attributes.className;
        delete attributes.className;
    }
    return <div ...attributes>...</div>;
}
// ...

But then I would have to manage separate template just for Vue, which I wanted to avoid in first place. At this point, it would be more straightforward to use standard Vue template syntax instead of JSX.

It would be nice, if this plugin could transform className into class (and htmlFor into for) attribute at compilation time, otherwise I would suggest to rename it to something else (e.g.: .vjsx), because it is not (fully) compatible with JSX syntax, that React defined first.

Thanks.