lit-analyzer icon indicating copy to clipboard operation
lit-analyzer copied to clipboard

Fix unknown tag when already element imported

Open abdonrd opened this issue 5 years ago • 2 comments

Simple example:

screenshot 2019-02-14 at 20 48 52

abdonrd avatar Feb 14 '19 19:02 abdonrd

I've looked into this issue and here are my comments/thoughts. Sorry my answer got very long :-)

A quick fix to your problem is to add "vaadin-button" to the lit-plugin vscode configuration called globalHtmlTags.

First of all it seems like the typescript language service (which powers the plugin) doesn't add js files from libraries without type definitions to the list of source files. Not even even with "allowJs" enabled. I'll keep on getting this to work but afterwards I will have to extend the parser to allow parsing define statements without strings as the first argument (which is definitely in the doable)

customElements.define(ButtonElement.is, ButtonElement);

However when I fix this the plugin can only tell that a given tag name exists. It's very difficult for me to automatically analyze which attributes a given web component supports.

So while I figure out the above here are some solutions.

With type definition files

This solution works right now but only if you are the author of a given library. If a library author ships a typescript type definition file with the library it will work perfectly out of the box. It worked fine for me after I added this file to vaadin-button node_modules/@vaadin/vaadin-button/vaadin-button.d.ts.

export class ButtonElement {
  disabled: boolean;
}

declare global {
  interface HTMLElementTagNameMap {
    "vaadin-button": ButtonElement;
  }
}
screenshot 2019-02-17 at 21 24 10

If you are running a typescript project it will also work out of the box if you add the above to any ts file in your project. However if you are not the author and you are not using typescript you are out of luck for a couple of weeks until I finish implementing support for vscode custom html data json format (see below).

Without type definition files

As type definition files are not for everybody it should also be possible to define elements for this plugin to use without having to add a typescript specific file.

Therefore I'm in the making of adding support for the same custom data json format that vscode recently added to their html language service. See https://code.visualstudio.com/updates/v1_31#_html-and-css-custom-data-support.

In general I follow this thread very very closely in order to build and support a standard way of allowing IDEs and tools to better understand web component defined in libraries.

To conclude, it's very much up to authors of libraries to add metadata to their libraries because it's simply not possible to properly analyze any web component :-)

runem avatar Feb 17 '19 21:02 runem

As noted in the documentation, it should work by having a @customElement tag-name JSDocs comment. We tried to put this both on the component class as well as above the customElements.define call in our JS source code, but it's not working :.

To reproduce:

npm i @lion/input lit-html
import { html } from 'lit-html';
import '@lion/input/lion-input'; // uses exports field in package.json to resolve

const templ = html`<lion-input></lion-input>`; // <-- lit-plugin warning for unknown tag

Inside lion

node_modules/@lion/input/lion-input.js:

import { LionInput } from './src/LionInput.js';

customElements.define('lion-input', LionInput);

node_modules/@lion/input/src/LionInput.js:

/**
 * LionInput: extension of lion-field with native input element in place and user friendly API.
 *
 * @customElement lion-input
 */
export class LionInput extends NativeTextFieldMixin(LionField)) { ... }

jorenbroekema avatar Mar 10 '21 12:03 jorenbroekema