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

Property case conversion #44

Closed
jpradelle opened this issue Jan 14, 2022 · 8 comments
Closed

Property case conversion #44

jpradelle opened this issue Jan 14, 2022 · 8 comments

Comments

@jpradelle
Copy link

Hi,
I'm trying to apply js property case conversion for PolymerJS web-types definition and generation based on modified version of marcobeierer's web-component-analyzer fork #25 (comment)

I don't get how to make it work
On IntelliJ 2021.3.1 I get that:
image
On following project, I expect forBaz to be not recognized and foo-baz recognized, I get the opposite.

Here is the full project:
package.json

{
  "name": "web-types-case-test",
  "version": "0.1.0",
  "web-types": [
    "./framework-web-types.json",
    "./component-web-types.json"
  ]
}

Framework generic definition framework-web-types.json

{
  "$schema": "http://json.schemastore.org/web-types",
  "name": "framework-web-types",
  "js-types-syntax": "typescript",
  "version": "0.1.0",
  "framework-config": {
    "canonical-names": {
      "/js/properties": "kebab-case"
    },
    "name-variants": {
      "/js/properties": [
        "kebab-case"
      ]
    }
  },
  "contributions": {
    "html": {
      "attributes": [
        {
          "name": "Properties",
          "description": "Properties expression",
          "value": {
            "kind": "expression",
            "type": "any"
          },
          "pattern": {
            "items": [
              "/js/properties"
            ],
            "template": [
              "#item:property name"
            ]
          }
        }
      ]
    }
  }
}

Generated web-components definitions component-web-types.json

{
    "$schema": "http://json.schemastore.org/web-types",
    "name": "web-components",
    "version": "1.0.0",
    "js-types-syntax": "typescript",
    "contributions": {
        "html": {
            "elements": [
                {
                    "name": "demo-test",
                    "attributes": [
                        {
                            "name": "foo-bar",
                            "value": {
                                "type": "string"
                            }
                        }
                    ],
                    "js": {
                        "properties": [
                            {
                                "name": "fooBaz",
                                "value": {
                                    "type": "string"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

index.html

<!doctype html>
<html>
  <body>
    <demo-test foo-bar="1" fooBaz="1" foo-baz="2"></demo-test>
  </body>
</html>
@piotrtomiak
Copy link
Collaborator

piotrtomiak commented Jan 15, 2022

@jpradelle Thanks for checking out Web-Types!

First of all, the configuration under framework-config applies only to the framework of the Web-Types file. So you would need to add e.g. "framework": "polymer" and then also add some rules when to enable that framework. The name conversion rules will then apply within HTML files, where the framework is enabled. Please note that there can be only one framework enabled in a particular file.

Second, there are two issues I've noticed in WebStorm:

  1. The changes to "canonical-names" and "name-variants" are picked up only upon restart.
  2. There is no way to restrict name matching, which means that both fooBar and foo-bar will match. I will add a new property to handle name matching.

There is also one more thing - the "items" reference within the pattern could have naming conversion applied "locally" and then we wouldn't need global rules for the framework.

@jpradelle
Copy link
Author

@jpradelle Thanks for checking out Web-Types!

Thank you for this awesome project ! I've been dreaming of that for few years :)

Thanks for your answer, IDE restart was part of the problem, I was able to enable case conversion with one more thing that I don't want to do:

As needed, I added framework configuration:

Updated package.json:

{
  "name": "web-types-case-test",
  "version": "0.1.0",
  "web-types": [
    "./framework-web-types.json",
    "./component-web-types.json"
  ],
  "dependencies": {
    "@polymer/polymer": "^3.4.1"
  }
}

I added framework configuration in framework-web-types.json:

{
  ...
  "framework": "@polymer/polymer",
  "framework-config": {
    "enable-when": {
      "node-packages": [
        "@polymer/polymer"
      ]
    },
    "canonical-names": {
      "/js/properties": "kebab-case"
    },
    "name-variants": {
      "/js/properties": [
        "kebab-case"
      ]
    }
  },
  ...

But that's not enough to have type conversion enabled for components described in component-web-types.json, I also have to add framework configuration in component-web-types.json:

{
  ...
    "framework": "@polymer/polymer",
  ...
}

And for that last part I think I should not have to do that:
I'm using PolymerJS and LitElement elements on same project because they are compatible and I could also even use raw web components or other things in the mix.
Then my idea was to define 3 files, one for PolymerJS framework (named framework-web-types.json in that sample), another one for LitElement framework. Those files are describing frameworks behaviors and that's completely OK to define framework and enable-when configuration.

For the last one (component-web-types.json in that sample) I don't want to define framework. This file is describing webcomponents elements, attributes, properties, events ... Use of those components are not related to a framework, and can be used in whatever framework or even outside of a framework.
For example using the defined component in component-web-types.json in a PolymerJS context, usage would looks like

<demo-test foo-bar="foo" foo-baz="[[foo]]"></demo-test>

In a LitElement context:

<demo-test foo-bar="foo" .fooBaz="${this.foo}"></demo-test>

demo-test component can be defined in Polymer, Lit or without framework, that wouldn't change the usage.

The idea is to have static files that describe frameworks syntaxes, and generate component description independently from framework.
This is currently working as is with LitElement definition as I don't need case conversion, the only issue is PolymerJS case conversion that needs framework definition to be added in generated component-web-types.

@jpradelle
Copy link
Author

To illustrate my point, in this project in which I only generated web-types files of a component library, I had to duplicate web-types files, one for polymer and one for lit, where the only difference is the framework property. And due to that I don't support other frameworks.

I think it would be awesome if every web-component project released web-types files in it. But for that I think framework constraint needs to be solved.

@piotrtomiak
Copy link
Collaborator

@jpradelle I've finally got some time to look at the issue. Unfortunately, you're right and there is no way to workaround at this point. I will need to figure out a solution, where framework rules affect framework-less Web-Types, when queried in framework context :) The solution will be present in 2022.1 at earliest.

@kloshar4o
Copy link

Hey, why am I getting error when I use array of paths

  "web-types": [
    "./framework-web-types.json",
    "./component-web-types.json"
  ]

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Array

@piotrtomiak
Copy link
Collaborator

@kloshar4o Which IDE and in which version are you using?

@piotrtomiak
Copy link
Collaborator

@jpradelle I've pushed fixes for the issues and they will be present in the next 2022.1 EAP, which will be released at latest next week. Additionally, I've added support for rules per reference, so for instance you'll be able to use:

{
  "name": "framework-web-types",
  "js-types-syntax": "typescript",
  "version": "0.1.0",
  "framework": "@polymer/polymer",
  "framework-config": {
    "enable-when": {
      "node-packages": [
        "@polymer/polymer"
      ]
    }
  },
  "contributions": {
    "html": {
      "attributes": [
        {
          "name": "Properties",
          "description": "Properties expression",
          "value": {
            "kind": "expression",
            "type": "any"
          },
          "pattern": {
            "items": {
              "path": "/js/properties",
              "name-conversion": {
                "canonical-names": "kebab-case",
                "match-names": [
                  "as-is"
                ],
                "name-variants": [
                  "kebab-case"
                ]
              }
            },
            "template": [
              "#item:property name"
            ]
          }
        }
      ]
    }
  }
}

instead of global rules, which I think is much better, as there might be some libraries, which make use of /js/properties and they would be affected.

jpradelle added a commit to jpradelle/polymer-web-types that referenced this issue Feb 21, 2022
jpradelle added a commit to jpradelle/paper-elements-web-types that referenced this issue Feb 21, 2022
jpradelle added a commit to jpradelle/material-components-web-types that referenced this issue Feb 21, 2022
@jpradelle
Copy link
Author

I can confirm this is working exactly as expected with version 2022.1 EAP (ideaIU-221.4501.155)
With your sample of code for case conversion and removing framework configuration on generic webcomponents web-types definitions.

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

No branches or pull requests

3 participants