Skip to content

Editor support for WebComponents #776

Open

Description

@octref

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

demo

  • User includes web-components.json and web-component-attributes.json in a project
  • User points to these JSON files with html.experimental.custom.tags and html.experimental.custom.attributes configurations
  • VS Code gets HTML completion and hover for the custom tags / attributes.

Some Background

Use Cases

The main two use cases are:

  • Someone ships my-wc-libs library. He includes web-components.json in his NPM distribution (similar to packages include d.ts files for TypeScript) and puts webComponents: "./web-components.json in his package.json. VS Code finds the JSON files to enhance its HTML support.
  • Someone just wrote my-component.js locally in a project. It would be awesome if an Analyzer (non-existent yet) would figure out the customElements.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.

  • What are some additional editor features that could be implemented for Web Components? For example, jump to definition on <my-component> in HTML goes to the JS source where the component is defined?
  • Would the WebComponents committee be interested in specifying a format for such JSON files?
  • Would WebComponents implement an Analyzer, similar to Polymer Analyzer for generating such JSON files on-the-fly?

Activity

  1. adamdbradley commented on Nov 29, 2018

    @adamdbradley

    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 lib.dom.d.ts global HTMLElementTagNameMap. Our json file sounds exactly what you are describing, so it'd be great to follow a standard, or at least a recommendation so it works well with external tooling.

  2. justinfagnani commented on Nov 29, 2018

    @justinfagnani
    Contributor

    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:

    • Tag name
    • Attributes
    • DOM interface: Properties, methods, superclass, implemented interfaces
    • Events fired
    • CSS Variables used
    • CSS Shadow Parts/Themes exposed
    • Slots
    • Permitted content
    • Permitted parents
    • Default / Permitted ARIA roles

    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 customElements.define().

    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.

  3. arjunyel commented on Nov 30, 2018

    @arjunyel

    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

  4. PaulHMason commented on Nov 30, 2018

    @PaulHMason

    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.

  5. manucorporat commented on Nov 30, 2018

    @manucorporat

    @justinfagnani
    I agree, we could and should be able to include more useful information, like CSS vars that apply (CSS autocompletion), the "slots" provided by a component or even the "type" of an attribute. While we all know HTML attributes might only be strings. The valid values differ:

    • Any string value
    • "true" | "false"
    • "on" | "off"
    • any union of strings (side: 'left' | 'right')
    • if an attribute is required or not

    I think the .json is looking good, no need to ship all this features the first day, very promising!

    @PaulHMason

    (even if that means just attaching the json description file content as a static property to the class definition)

    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
    Question, why do we need "two" .jsons?

  6. manucorporat commented on Nov 30, 2018

    @manucorporat

    btw, it's working!!
    screenshot 2018-11-30 at 10 17 05
    (stenciljs/core#1256)

  7. willi84 commented on Nov 30, 2018

    @willi84

    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

  8. pjmolina commented on Nov 30, 2018

    @pjmolina

    Hi!
    Joining the discussion.

    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.
    My two cents on it: A working draft for a Spec: Typed Web Components Spec
    Not complete, (needs to add Slots and more) but accepting Pull Request ;-)

    It is inspired by OpenAPI to provide a JSON/schema spec to be language and framework agnostic.
    But at the same time, we can derive *.d.ts files or viceversa for example to leveraged typed languages.

  9. caridy commented on Dec 1, 2018

    @caridy

    Great stuff. My only immediate feedback is to not focus on customElements.define() via Analyzer, mainly because these two reasons:

    • many folks will just let the registration process to be mechanical as part of the build process rather than explicitly authored, which means that you author a class with all the stuff in there but the definition of the tagName associated to that class is not something that you have to author.

    • many frameworks will be able to compile to web-components, (e.g.: VUE or React), which is a process that will happen as part of the compilation step.

    Having an out-of-band configuration file to describe the shape of your component, and the inheritance seems to be good enough.

  10. octref commented on Dec 2, 2018

    @octref
    Author

    @adamdbradley Do you have a pointer to how you are using HTMLElementTagNameMap?

    @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.

    "two" .jsons?

    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.

    WASM

    @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.

    self-describing web components

    @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.

    types for Web Components

    @pjmolina I don't know enough about WC to give opinions on this matter. Bringing types to Vue has been very difficult, though.

    not focus on customElements.define()

    @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 html-language-service will expose APIs for loading additional tags/attributes, and I can imagine a React analyzer generate metadata for its components, feed them to html-language-service to enhance lit-html.

  11. octref commented on Dec 2, 2018

    @octref
    Author

    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.

    @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.

    Given that the typings, definitions, and jsdoc tags are interop points between tools, I think we should start with defining their formats.

    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:

    • When JSON adds a tag definition (with attributes/self-closing-or-not and other metadata), editor should:
      • Handle LSP Completion for tag/attributes
      • Handle LSP Hover for tag/attributes (show description)
      • Provide Diagnostics if a required attribute is missing, or if a non-self-closing tag is self-closed.

    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.

    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

    Feel free to tag me or @mjbvz in the specific issues.

  12. arjunyel commented on Dec 3, 2018

    @arjunyel

    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 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

  13. manucorporat commented on Dec 7, 2018

    @manucorporat

    @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:
    https://unpkg.com/@ionic/docs@4.0.0-beta.17/core.json

  14. bkelley13 commented on Jan 23, 2019

    @bkelley13

    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?

  15. 21 remaining items

  16. octref commented on Oct 28, 2019

    @octref
    Author

    I would consider it a subset of what is currently in vscode.

    @daKmoR I'd say it's a superset. Think of it this way:

    • slots, events etc are specific to your WC. You compile them together into HTML API doc, and browser render it.
    • Similarly, you compile description, slots, events into a Markdown and give that to VS Code as the description field, which renders that in its hover and auto-completion widgets.
    • I think keep the bridge just the Markdown formatted description is good. There's a 1-1 relationship between what data you feed VS Code & what you see on UI. Saying "now VS Code's custom data format would include slots, events, cssProperties and dictate how they should be rendered" limits your freedom to organize the message in the auto-completion widget, and these don't apply to scenarios outside WC.
  17. daKmoR commented on Oct 28, 2019

    @daKmoR

    @octref thx for clarifying on the superset - I fully agree 👍

    also, I fully agree on that does not make sense to add slots, events, cssProperties to vscode-custom-data.
    Let's only add them to custom-elements.json - as there we need it for API docs and such 👍

    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 🤗

  18. castastrophe commented on Oct 21, 2020

    @castastrophe

    There are also "alternatives" - for example, @castastrophe let me know that they are using a JSON schema to document their web components. Here is an example https://github.com/patternfly/patternfly-elements/blob/master/elements/pfe-band/src/pfe-band.json

    @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: PfeFoo.properties, PfeFoo.slots, PfeFoo.meta, for information about the component. This was a critical update for us as it allowed our base class to manage prefixing, observer, and cascading. cc @mwcz @kylebuch8

  19. piotrtomiak commented on Jan 18, 2021

    @piotrtomiak

    @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 web-types to be a de facto standard for any web-framework, not just Vue.js - we had to evaluate it's usefulness and gather feedback before moving further. I can see that a lot has happend in Web Components community in the meanwhile. What is the currently accepted format for describing WebComponents library?

    @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 web-types schema? Our goal as JetBrains is not to force any standard on the community, but to drive community to accept a single format for exchanging information about JavaScript library contents, which we believe will benefit everyone. If you don't feel that hosting an open source repo under JetBrains org is good for community we are open for transferring the repo under some community organization. As I see now, custom-elements.json being shipped with some Web Component libraries pretty closely resemble web-types JSON. We have resources to support yet another JSON format, but what about other lightweight text-editors?

  20. lpj145 commented on Jan 13, 2022

    @lpj145

    @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...

  21. piotrtomiak commented on Jan 15, 2022

    @piotrtomiak

    @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.

  22. MSFTKonnor commented on Mar 28, 2023

    @MSFTKonnor

    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?

  23. break-stuff commented on Aug 17, 2023

    @break-stuff

    I know this is an old thread, but has there been any movement on this ideation?

  24. max529 commented on Aug 17, 2023

    @max529

    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.

  25. break-stuff commented on Aug 17, 2023

    @break-stuff

    @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.

  26. break-stuff commented on Aug 17, 2023

    @break-stuff

    I also wish VS Code had better custom element/emmet integration. I don't believe emmet works for custom elements.

  27. max529 commented on Aug 17, 2023

    @max529

    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.

  28. trusktr commented on Oct 13, 2023

    @trusktr
    Contributor

    @octref Hello, I'm late to this conversation, but I'm super interested in support for flavors of html template tags. Have you (or anyone else here) worked on making this possible for different framework's html template tags?

    For example, I use (and contribute to) the Solid.js html template tag in my custom elements, and would like type checking in the templates. Here's sample template in one of my custom elements:

    https://github.com/lume/lume/blob/b0c2cdcf8498fae1280c8121160ac6ff328c1588/src/cameras/CameraRig.ts#L207-L238

    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 html template tags. Solid's html works a little diffferently from Lit's, so it would need slightly different implementation.

  29. ulrischa commented on Mar 17, 2025

    @ulrischa

    I think more work needs to be put on the definition what can go into what slot. With this a true block definition could be possible (like Gutenberg blocks)

  30. sashafirsov commented on Mar 18, 2025

    @sashafirsov

    Without schema based parser, the content mixing as HTML, XSLT, CSS, JS, XPath, SVG becomes a nightmare to deal on the scale. No wonder that solution which excludes other tiers are winning. Like JS-centric web apps. That solves a transparency problem and source-availability in editors, debugger, and bundling/optimizing tools.

    For example, even for simple case as inline custom elements declaration (DCE or inline JS), the parser with access to AST is needed for IDE editor support. Otherwise the regeneration of IDE-specific metafile and its reload is only option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions