-
Notifications
You must be signed in to change notification settings - Fork 376
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
Editor support for WebComponents #776
Comments
I think this is a great discussion to start. With stenciljs, the compiler is running static analysis on all of the components, then auto-generating a json file, JSX type definitions, and adding to typescript's |
This is awesome to see :) I have a bunch of thoughts in this area, since we've been working on similar things for a few years. First, is that elements have a very right API surface, not just limited to attributes, and for the best experience we need to take all of them into account:
I think the easiest way to describe the DOM interface if via .d.ts files and HTMLElementTagNameMap, and JSON is probably ok for the rest, modulo some cross-file references like the types of Events. I hope that other IDEs and toolchains would be ok with using .d.ts for the interface description. The Polymer Analyzer generates a JSON file already that describes a lot of this information for elements, inferred from the prototype chain and jsdoc annotations. The Analyzer is not very Polymer specific in most places, aside from some bundled plugins to recognize Polymer-specific declarations. It does analyze vanilla elements that extend from HTMLElement and/or are registered with plain We would be very interested in contributing infrastructure to a non-Polymer-branded analyzer that VS Code and the rest of the ecosystem can easily use. We would also be very interested in reading this information from package.json and using it to drive webcomponents.org, rather than doing analysis on published npm packages. Given that the typings, definitions, and jsdoc tags are interop points between tools, I think we should start with defining their formats. Then on our end we can work on updating the Polymer Analyzer to output this format and support new jsdoc tags rather quickly, and webcomponents.org to read the formats. Note: We've started looking at adding better analysis support to the lit-html VS Code extension, and the biggest immediate roadblock is the lack of integration between the HTML and TypeScript Language Services. The HTML Language Service doesn't recognize that a tag name maps to a class, so it looks like we'd have to just re-parse the HTML in a separate service. cc @rictic there. |
It would be cool if the element metadata was available via JSON as well :D Now that WASM supports DOM access I imagine it would be possible for WASM languages like Rust to parse that JSON and offer type completion when working with custom elements |
I'm more in favour of self-describing web components (even if that means just attaching the json description file content as a static property to the class definition), that way browser dev tools could also be a bit smarter when working with web components (but I suppose they could work with the external files in a similar way to source maps). I also think it's worth considering how web components could be made more compatible with design surfaces - being able to register extended information, scoped registries and being able to remove registered custom elements would make things a lot easier. |
@justinfagnani
I think the
I don't think we should make web components bigger to fix a DX issue, not a runtime one. It's a matter of tooling, polymer, stencil or even VScode itself could parse web components and "auto-generate" whatever the metadata is required. @octref |
btw, it's working!! |
Apropos webcomponents: maybe in the same view it would be cool to give support for inline templates (like in angular) to provide the html featureset of auto completion, highlighting etc for custom selectors or web components |
Hi! I fully agree we need to come up with a standard way to expose types for Web Components and love to see more people demanding it. This will enable tooling support for WebComponents. It is inspired by OpenAPI to provide a JSON/schema spec to be language and framework agnostic. |
Great stuff. My only immediate feedback is to not focus on
Having an out-of-band configuration file to describe the shape of your component, and the inheritance seems to be good enough. |
@adamdbradley Do you have a pointer to how you are using @manucorporat Thanks for the quick PR. Seems stencil is already generating metadata for compilers and you just added one more JSON output? Glad to see such thing baked into frameworks.
No specific reasons. I don't know what setting to call if I combine both. And there are frameworks like Mavo which adds only global attributes but not tags.
@arjunyel Yep. Each language targeting web will embed HTML (like JSX) or become embedded by HTML (like Vue). These metadata provide foundation for building Language Service to support those cases.
@PaulHMason You can see the discussion I brought up for Vue: vuejs/vue#7186. I think we should leave this discussion to each framework. As long as they generate JSON of a specific format, VS Code can use it to enhance the HTML editing capabilities. For WC, I don't know enough on this matter to give an opinion. For Vue, it depends on what experience we to give for TS.
@pjmolina I don't know enough about WC to give opinions on this matter. Bringing types to Vue has been very difficult, though.
@caridy That's correct. However we should have one that can handle build outputs (glad @justinfagnani is willing to help here). This is useful for people shipping WC libraries. It's impossible for VS Code to support each framework. Our approach has been offering building blocks (like vscode-html-languageservice and let framework Language Servers build upon on them (lit-html, Vetur). The |
@justinfagnani That's awesome to hear! Thanks. I think your long list is "JSON metadata WC should generate for empowering other tools", which would be a superset of what editor needs. Let's limit the scope of the discussions here... For VS Code's HTML we are currently only thinking about declarative contributions (like JSON files), not JS plugins like TS Server Plugins. We might do it in the future though, so you could wire a ARIA-validation-plugin into the HTML Language Server.
I agree. We should start specifying a contract between the JSON file and editor features & LSP methods. With this you can work on improving the Analyzer and us on the HTML Language Server to support this contract. For example:
Notice the JSON data might be reused for VS Code's css/emmet support too. For example, CSS selector completions should include custom tags, and emmet should expand custom tags.
Feel free to tag me or @mjbvz in the specific issues. |
For the HTML language server I understand it basically just needs attributes, but for all other tooling like my WASM idea we need the other data such as the DOM properties, I'd like to see Justin's list become the spec if possible. BTW I appreciate you starting this issue, I'm excited to see where it ends up :D |
@octref yeah! we have already a bunch of different outputs, like markdown, json, angular bindings, react bindings... For the record, check out our "docs-json" format that includes all information we have: |
Is there a way to provide a list of options for attributes? ie, if I have my-component, with my-attribute and my-attribute has a choice of {left|right}, could this be done? |
With 1.31 VS Code has formalized the data format a bit. We also have some docs and JSON schemas for the JSON files. @bkelley13 Yep, that can be done with |
First of all, thank you for your great work on this JSON format @octref 🎉 Right now the format has a lot of momentum. Experimental support in VS Code, the Stencil compiler generates it and it’s considered for the reboot of webcomponents.org. I would really like to get the discussion going around expanding the format, and I hope my thoughts and suggestions will help this discussion. Here I suggest some features that I think would be a great addition for a potential next version of this JSON format. I know there are some open questions in my post here, but I'm pretty much posting these suggestions to start the discussion. Go here for TLDR. PurposeI would like to briefly outline the purpose of this format (at risk of repeating the first comment on this issue). This JSON format is a common way of describing custom elements. A library shipping custom elements should include a JSON file with metadata describing custom elements provided by the library. This format can be used to give editor support, generate documentation/demos and much more. I think the format should be simple enough to be written by hand, but a library maintainer would likely be using a tool to generate them. The tool that the maintainer chooses would depend on which library they used to build the elements (e.g. the Stencil compiler already outputs this format). I also think it should be a goal that it’s possible to describe the API of built-in HTML elements using this format. SuggestionsDescribing membersI suggest the next version of this format supports the following 4 DOM features:
In my experience, these 4 features of a custom element API are the most important to know for a consumer. The existing version of this JSON format already supports attributes. It would make sense to add 3 optional fields called
Just like the existing The new Based on the aforementioned, the JSON would look like this:
Note that an unnamed slot has an empty string as the name because Relation between property & attributeIn the example above, two related members called In order to describe the relation between a property and an attribute, I think we need to look into the following:
To solve (1) I suggest adding To solve (2) I suggest adding
Describing typesThe existing version of this format only supports string enumeration types (by using I think this format will need to have some way of specifying more complex types than string enumeration types. This is applicable for both attributes and properties. Even though all attributes are strings as far as the DOM is concerned, I think it would be very useful to tell what type of value the attribute is coerced/converted to. Imagine reading the documentation about an element or using an IDE-plugin to autocomplete attributes: Here it would be great to know that the value given to e.g. Let's look at some examples from built-in elements: ‘max’ on With all this in mind, I suggest that we explore adding an optional Here is an example of how it could look:
In the following sections, I will explore what using jsdoc gives us and the challenges that follow. It could also be interesting to investigate if it makes sense to use Typescript definition files instead, but I fear that making the JSON format dependent on Typescript for types would not be the right way to go. Therefore I chose to go with jsdoc type expressions, but there might be something even better. I'm very interested in hearing what you think. I'm aware that this opens a lot of questions that will need to be considered. Most notably these two questions which I will try to address in the next sections:
values and typeAs mentioned before A string enumeration could with valueSetWe could also allow adding
Complex typesSupporting complex types comes with some challenges. This is the point where I'm the most in doubt, so I look very much forward to hear what you think. Let me give an example of a challenge: If we describe a property called
Types and eventsThe
Default property valuesProperties usually are holding the "local" state of a custom element, therefore, it is highly interesting for users to know these default values/states. Attributes do NOT have a default as users are providing the html. However, when using the combination of a default value and reflect, then a custom element will get set a certain attribute if not already defined by the user. We could add
DeprecatedIt would be useful to add A tag gets deprecated
A property or attribute gets deprecated
ExamplesIn JSDoc a well-used feature is @example allowing to provide copyable code snippets for your users. We can extract that to be easily usable by documentation tools. Can be used for members and for tags. The field to describe examples could be
MethodsIt would be very useful if it was possible to document methods of a custom element using this JSON format. When using and extending custom elements it's rather important to know which methods are available and therefore having them available for documentation would be a big plus. This can be done by adding This is an example of how it could look like:
Summarizing propertiesIf these suggestions are accepted, properties will become the entry with the most info. e.g. it will have additionally “default”, “type”, “attribute” and “reflect”:
PathI suggest adding This information would be useful to e.g. IDE-plugins and allows to find source files and Typescript definition files.
GlobalsIn the existing vscode JSON format, global attributes can be described using In addition to global attributes (like the ‘title’ attribute), there also exists global events (like the ‘click’ event). Therefore I suggest that the existing
Note that this would be a breaking change. I chose to include Sharing the JSON fileI have heard two different suggestions of what to call the JSON file: I also think there could be value in being able to point to this file using a "customElements" field in However, I'm not sure if adding ConclusionOverall we would like to encourage people to publish their (npm) packages including a The file should look something like this:
I tried to suggest as few additions/changes to the format which I think will result in the greatest improvement. The purpose of this post is to start the discussion around the format with some concrete suggestions and considerations. I'm sure that there are many questions still left to consider and perhaps not all suggested additions are needed. I added experimental support for some of what I suggest in this comment to web-component-analyzer. I will add more features to the experimental support during the next couple of days. This way you can get an idea of how this format would look based on your own custom elements: npx web-component-analyzer analyze my-element.js --format json --outFile custom-elements.json Note: you can also use Thanks for reading this comment. I look very much forward to hear what you think about these suggestions. |
@runem awesome write up :) I think that we should open a repo somewhere, possibly in the /webcomponents/ GitHub org, to specify the custom-elements.json format. Then we can have a page the the format description, multiple issues, PRs, etc. Also, as a really high-level point about the format: The set of information we need for web components is a superset of what's needed for JavaScript/TypeScript in general. This is especially clear when you consider class methods and properties and their types. Web components are just classes with extra structured API surfaces. I'm not aware of any well-specified format for JS docs, but the output format of the Microsoft API Extractor seems like a good start to me: https://www.npmjs.com/package/@microsoft/api-extractor It would be ideal to me to have both a specified JS/TS analysis format, and a web components extension to it. |
@runem WOW - this is awesome!! I’m still digging into all this but at a high level, this looks like it’ll solve a ton of the growing pains I know me and my team are working through as our design system continues to ship almost everything as a web component... Up till now we’ve primarily used JSON schemas to document / manage APIs (especially when dealing with backend Twig integration). Unfortunately, the JSON Schema spec just can’t cover the deeper documentation needs of Web Components: deprecating props, events, methods, slots, CSS custom properties, etc — so I’m SUPER excited to see a more standardized (+ IDE-supported Can’t wait to dive more into this (plus the web component analyzer tool)! 😊 |
Hey @runem, thanks for the writeup. To your suggestions, I'll have a more detailed response later — preparing for a conference and boarding plane soon. But here are some high-level notes:
Some other notes:
We marked it stable last month. Here's the repo: https://github.com/microsoft/vscode-custom-data The format is versioned and we plan to roughly follow SemVer. Now the development of this custom data format is mostly driven by editor language features such as completion, hover information etc. There's no consumer generating docs from such data so we haven't considered fields that would be useful for that purpose.
That's what we are doing already. See https://github.com/microsoft/vscode-custom-data. |
Is the example web-components.json the latest version? it uses "label" instead of "name"? could be that I missed that change 🙈 imho the minimum to make it useful for more than "just" vscode depends on what it is used for Use Case Docs:What web component users are interested
and adding a short description for all those "names"/"labels" basically outline what I can expect from this custom element / web component. => web-component-analyzer can already output markdown documentation. Right now it's using the "internal" data for it... but it would be nice if Use Case Web Component Catalog:Allow searching ala npm search but for web components only. info needed is the same as for Docs (e.g. index all the names/labels/descriptions and let the user search through it all) Use Case Playground:An example would be storybook with can render a web component and give knobs to modify all the states of it. It needs
A description is not needed in that case; A Knob Type can in many cases be derived from the actual type. Still, there will need to be a method of overriding it. Suggestionadd a property jsDoc which "just" contains the raw jsDoc from the code if available.
That way the json format stays simple and tools use cases can still get the information they need. If at some point everyone uses the same jsDoc we can make it a separate property in the json. Possible ways forwardadding minimal:
adding for docs (e.g. above +):
adding full (e.g. above +):
Example for docs: {
"tags": [
{
"label": "open-shadow",
"description": "Open Shadow DOM Component",
"properties": [
{
"label": "text",
"description": "The text inside the component",
"jsDoc": "/**\n Some longer description\n * @type {string} * @example ... \n * @storybook-knob ColorPicker\n */"
}
],
"events": [
{
"label": "colorchange",
"description": "This event will fire whenever 'color' changes"
}
],
"slots": [
{
"name": "",
"description": "Main content"
},
{
"name": "left",
"description": "Left content"
}
]
}
]
} |
Wow this looks awesome, we use a similar file to describe all our components where I work, If this takes traction, we can switch to this standard. One additional information would be nice, we use a lot of inheritance for our custom elements (internally we use something similar to lit-element) and also make use of extending built-in elements for progressive enhancement.
for our tooling we also add the identifier of the exported class which represents the custom element and the path of the js module that exports the class (path relative to our |
So we are working on a catalog to index web components and the idea is to add every package that has a PS: |
Properties make sense when you only want to write to property, e. g. lit-element has syntax to either write to attribute or to a property. It's quite common if you don't need the property to reflect an attribute on the element. For events, I suppose autocompletion for My personal take on this issue is that if there can be one source of truth for as much documentation for a component, that would be great. I understand your goal is to make editor support via autocompletion easier, and I agree that's a great endeavor. Though some way to auto-generate docs outside a code editor from this would be amazing. I can see that methods don't make sense for the code editor auto-completion but they'd be very beneficial for general docs. |
I hadn't seen this one. I think it's a little unfortunate to have repos spawn on separate IDE owners orgs to try to create standards that span many tools beyond IDEs. I think at this point we need a central repo to work up a spec. I can open one in https://github.com/webcomponents and then we can have individual issues for each topic and organize the conversations much better. |
Ok, I created a new repo at https://github.com/webcomponents/custom-elements-json I made a few seed issues around goals, requirements and such. It would be great if we could gather a good discussion there. |
Looking at the example syntax for web-types: https://github.com/JetBrains/web-types/blob/master/examples/vue.web-types.json, It looks to me that the two schemas aren't that far apart. It looks like the "html" section is quite close to the VSCode format, and even with the https://github.com/runem/web-component-analyzer format, only far more exhaustive. I don't see anything in that section that contradicts the VSCode format, only more stuff. I might be missing something. So kind of good news, maybe? |
Storybook API TableStorybook now supports an api table in docs mode for your components which is also powered by a and then you can use it via See the following demo. Storybook API PlaygroundYou can also auto-generate an "api" playground - again based on metadata within ThoughtsThe used custom-elements.json in that example is not too different. I would consider it a subset of what is currently in vscode. For documentation and api playground there is more/different information needed then when doing autocomplete in vscode. However, as long as the data is not contradicting each other we should be fine right? The types used in the example are more "typeHints" e.g. for documentation so that users can read what the name of the type is that is expected. Or what kind of value the css variable is used for. It's not really a "true" type check or so... Web Component API viewerThere is also a very nice project api-viewer-element. Which generates full API documentation and API Playground purely based on a custom-elements.json. Again it adds "typeHints" and additionally jsDoc See the live example ResumeA lot of stuff is happening and it seems to be really useful to add more info (besides what is truely needed in vscode). As long as it is considered a subset it should be fine for everyone right 🤗 Sooo enough for now let's head over to https://github.com/webcomponents/custom-elements-json and spec that thing before people go too crazy 😬 |
@daKmoR I'd say it's a superset. Think of it this way:
|
@octref thx for clarifying on the superset - I fully agree 👍 also, I fully agree on that does not make sense to add Looking back at the thread I have the feeling there have been some missundestandings 🙈 as far as I know it has never been the goal to bring all web component meta data into vscode-custom-data 🤔 more to bring them into a common file which would not contradict the vscode-custom-data... I'm sorry if there was confusing but I have a feeling it's now on the right track 🤗 thx for bearing with me/us 🤗 |
@daKmoR Thanks for the mention! So we are actually walking away from our schemas at the moment. We're implementing a built-in property management system in our base class and as such, the JS of the custom element is now the source of truth for the attributes, slots, and metadata. Going forward, you'll be able to query: |
@daKmoR @justinfagnani Looks like I am a little bit late to the party :/ I wish someone had pinged me on this topic earlier. I've finally moved to the next phase of improving @justinfagnani Creating yet another standard makes it really hard for each IDE and documentation tool to support every framework out there. Can we work on merging your schema with |
@piotrtomiak i already see web-types from jetbrains and i like so much what yours done, in the same way custom-elements.json as pretty good too, but we had to admit maybe we enter in a trouble (or we're already), because any ide supports and implement your own way, what guide us back in history to wars of browsers... i think is so best if we have only one way to supports ide, so i guess we can make project on rust or any other language to implement global library component analyzer for majority of libraries like: angular, vue, react, svelte, lit-element and so on... |
@lpj145 Web-Types or custom-elements manifest is just some metadata file to describe what's in the library. We are continuing our work on Web-Types, since it solves more than just one case - it works for Angular, Vue, Web Components, React, Svelte, Font-awesome Icons, Htmx etc.. A main feature of Web-Types are patterns, which allow to describe a lot of framework features without coding. We plan to open-source the code, which allows to evaluate patterns, once it matures enough, and could be reused by other IDEs. |
I've been reading through and I'm curious if there's been any consideration for dynamic tag names. (It's a long thread, maybe I missed it) At work, we use prefixes to allow multiple versions of our WC library to be run at the same time. here's an example index.d.ts I've been using with Preact that gives me full autocomplete for regular HTML tags and was curious if it'd be possible with the JSON files proposed. https://gist.github.com/MSFTKonnor/a28d93cd88240a24cba884d5a77be9e8 or am I looking at needing to run a custom language server to generate the file htmlData JSON files on the fly that can account for different namespaces? |
I know this is an old thread, but has there been any movement on this ideation? |
I've created a framework based on vscode's server protocol language so that it can be integrated everywhere. A vscode extension is already available. It allows you to generate web components based on Typescript, HTML and SCSS languages. The aim is to be able to easily make custom attributes and tags available during autocompletion. If you're interested I'll be happy to send you the link (or if you search my github profile you'll find it) but I want to avoid self-promotion here because that's not the aim of this community. |
@max529, that sounds really interesting! I have created some tools to generate the appropriate data files for VS Code and JetBrains IDEs (web-types) based on the Custom Elements Manifest. The thing I wish existed is the ability for VS Code to auto-detect the config files and apply them to the editor automatically. JetBrains IDEs already do this with web-types and it's an excellent way for developers to get up and running quickly with custom element libraries. |
I also wish VS Code had better custom element/emmet integration. I don't believe emmet works for custom elements. |
I'm having trouble implementing emmet in my extension too. The html.customData is a problem when working live. You have to reload the window each time to have the autocompletion up to date, which isn't cool when working on large projects. The problem with simply installing a custom element library is that auto-completion has to work in every language that can write html (html, jsx, svelte, etc.), which is a lot of work. And people who already use a framework don't see the point of using a native web component library outside of their framework. If you find my idea interesting or if you want to share more about the possible integration of the Custom Element Manifest in VSCode, you can write to me privately (my email is on my github profile) to discuss it. |
@octref Hello, I'm late to this conversation, but I'm super interested in support for flavors of For example, I use (and contribute to) the Solid.js I have type checking support when using JSX, by wiring type defs into React/Solid/etc JSX interfaces. But I currently have no type checking when using |
Hi, this is Pine from VS Code team. I'm working on expanding our HTML Language Server to better support WebComponents. I'd like to get some feedback from the WebComponents commitee / community on implementing WC editor support.
I also work on Vue Language Server where I'm already shipping such support for Vue-based frameworks.
Current Status
https://github.com/octref/web-components-examples
web-components.json
andweb-component-attributes.json
in a projecthtml.experimental.custom.tags
andhtml.experimental.custom.attributes
configurationsSome Background
Use Cases
The main two use cases are:
my-wc-libs
library. He includesweb-components.json
in his NPM distribution (similar to packages included.ts
files for TypeScript) and putswebComponents: "./web-components.json
in hispackage.json
. VS Code finds the JSON files to enhance its HTML support.my-component.js
locally in a project. It would be awesome if an Analyzer (non-existent yet) would figure out thecustomElements.define
calls, generate such JSON files and feed them to the HTML Language Server to enhance its functionalities. When the user navigates to a HTML file, he should get HTML completions for the WebComponent he just defined.Discussions
I'd like to get some input for questions below. But if you have other questions / concerns, feel welcome to chime in.
<my-component>
in HTML goes to the JS source where the component is defined?The text was updated successfully, but these errors were encountered: