Giter Club home page Giter Club logo

lit-analyzer's People

Contributors

43081j avatar abdonrd avatar andreasbm avatar andrewjakubowicz avatar benjamind avatar bicknellr avatar bigjpg avatar dependabot[bot] avatar dfreedm avatar felixschusi avatar jhonaker avatar justinfagnani avatar paglobal avatar rictic avatar runem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lit-analyzer's Issues

Improve custom element parsing

This issue improves parsing of custom elements and makes it possible to distinguish between properties and attributes. Here are my considerations/thoughts.

TLDR: goto conclusion for a conclusion :-)

lit-html allows setting both attributes (myattr="value) and setting properties on the element (.myprop="value").

In reality any property (and any attribute) can be set on any element so I'm considering allowing doing this through a configuration. I'm a bit in doubt of allowing this by default because I fear it would introduce a risk that spelling mistakes wouldn't be cached by the plugin.

Built in HTML tags

All in all for built in HTML tags I use the list of attributes from (vscode-language-service)[https://github.com/Microsoft/vscode-html-languageservice) and plan on using the typescript lib.dom.d.ts for finding properties on individual elements. I haven't decided what to do on the "null vs undefined" challenge described below.

Null vs undefined
Also properties have different behaviours when it comes to null and undefined. For example when setting HTMLTextAreaElement.value it clears the text on the value null and sets the text "undefined" on the value undefined. (See this codepen https://codepen.io/runem/pen/vbqvqq) However when setting min on an of type "range" the attribute value is set to min="null". I'm not sure of where to find more information on these behaviour (other than reading the individual specifications) so if anyone knows, please give me a tip.

Custom elements

When parsing custom elements (non LitElements) we only have to look at static get observedAttributes() { return ['c', 'l']; } and public class fields. In addition we should also look at public properties defined on HTMLElement.

Attribute only
It's possible to have observed attributes only (without a property behind):

class MyElement extends LitElement {
  static get observedAttributes() { return ['c', 'l']; }
}

Property only
And it's possible to have properties on the element without an attribute behind. This plugin would look at public class fields to find these (This can be done in Typescript and in Chrome 72)

class MyElement {
  myProperty = "hello";
}

I also plan on looking at assignments in the constructor to find properties on a given class.

LitElement custom elements

Parsing LitElement custom elements is a superset of parsing custom elements.

Default:
When using the lit-element property decorator (@property() size) (or static get properties()) the property name is by default added as an observed attribute lowercased.

By default, LitElement creates a corresponding observed attribute for all declared properties. The name of the observed attribute is the property name, lowercased

Property only:
When using the "{attribute: false}" config the corresponding attribute is not observed.

Backer attribute with another name:
When using the "{attribute: 'other-attr'}" config the corresponding attribute is observed with another name.

Conclusion

To conclude I plan on keep two lists on each html tag: a list of attributes and a list of properties.
I will also have to expand the custom element parser to include the points I describe above. This primarily includes better support for attributes/properties defined without the lit-element property-decorator :-)

Hide vscode parameter hints for html/css tagged template literal

Sometimes, when working inside a lit-html tagged template literal, a useless parameter hint will appear describing the parameters of the html or css tagged template literal. This hint will stay and cannot be set to hide itself after a timeout. The only option right now is to completely disable parameter hints for vscode with "editor.parameterHints.enabled": false.

See the frustrations of the parameter hint below:

signaturehelp

I think it would be a great addition to lit-plugin if it prevents this specific parameter hint to appear.

Discussion/Question Linting/CI

hey,

first of I am really impressed ๐Ÿค—
a lot of good stuff here ๐Ÿ‘

Especially all those checks for attributes (including types) really powerful ๐Ÿ’ช
I'm just wondering is there a way I could do this check via a CI as well? ๐Ÿค”

A helping VSCode improves developer experience a lot - but as a maintainer of a library I really would like to check if the code (that comes in via a PR is "good") so an automatic check that tells me everything is good would make it easier to review :)

I am just thinking out load her but an integration via eslint would be awesome... just run eslint in the ci and you see the errors?
I'm probably pretty naive here as I don't know how coupled this is to VsCode... but would there be any chance for it? ๐Ÿ™

HTML Attributes can use either ' or " for quoting values

These are equivalent:

html`
  <a href="foo.html" target="_blank"></a>

  <a href='foo.html' target='_blank'></a>
`;

However, the analyzer emits an error for the second one, because it considers the type of the value to be '\'_blank\'' instead of just '_blank'.

Warning when using boolean type expression in attribute binding

An attribute binding using a boolean type expression will result in the following problem.

html`<input disabled="${true}" />`  /* <input disabled="true" /> */
html`<input disabled="${false}" />`  /* <input disabled="false" /> */

Both examples would result in a disabled input field! Using "?" would be the correct way of doing it.

html`<input ?disabled="${true}" />`  /* <input disabled /> */
html`<input ?disabled="${false}" />`  /* <input /> */

Therefore this plugin should warn when assigning a boolean to an attribute and should suggest using "?" instead.

Rule: Warn when calls to super are missing

Suggestion: Create a new rule to warn when calls to super are missing for:

  • super.connectedCallback()
  • super.disconnectedCallback()
  • super.attributeChangedCallback()
  • super() (in constructor)

Forgetting these calls will often result in the custom element not working as intended at runtime.

The rule could be called something like no-missing-super-call

Support for 'playsinline' on HTMLVideoElement

The HTML Specification states:

The playsinline attribute is a boolean attribute. If present, it serves as a hint to the user agent that the video ought to be displayed "inline" in the document by default, constrained to the element's playback area, instead of being displayed fullscreen or in an independent resizable window.

It would be awesome if ts-lit-plugin supported it.

screen shot 2019-02-18 at 3 02 58 pm

cssTemplateTags name not working

Unable to to leverage the cssTemplateTags configuration.

Opposed to using css we want to use scss literal tag name however the extension ignores this and only css works when using VS Code setting configuration.

Link to extended docs in error messages

It'd be nice to have a place to put longform guidance for what to do about different error messages. One pattern I've seen is to add a short url onto the end of error messages. Like:

Unknown property 'naem'. Did you mean '.name'? https://lit.example.com/unknown-prop

19    <name-tag .name=${'Alex'}></name-tag>
                 ~~~~

With a docs site at lit.example.com/unknown-prop that describes why that error commonly happens and what to do about it.

When input type is date, min and max should accept date string

From MDN's documentation

You can use the min and max attributes to restrict the dates that can be chosen by the user. In the following example, we sett a minimum date of 2017-04-01 and a maximum date of 2017-04-30

When I was attempting to programmatically set min to the current date

html`<input type="date" min=${new Date().toISOString().split("T")[0]} />`

I received an error stating:

Type 'string' is not assignable to 'number' no-incompatible-type-binding(2322)

This may be a duplicate of #43

Validate the configuration given to lit-analyzer

The configuration given to lit-analyzer is not validated as of now.

First of all, I think the CLI should throw on invalid values, but ts-lit-plugin should only log warnings (no reason to crash when running in the IDE).

Therefore, I think that we should implement one of these solutions:
a. export a validateConfig function that validates the raw, partial config.
b. extend makeConfig with an option to assert values (perhaps a callback that is called on invalid config values).

I also think makeConfig should properly fall back to default values when encountering an invalid value (which it doesn't do for all attributes right now).

Running type checks from command line / as tsc plugin

We'd really like to run the template type checks as part of the tsc compilation. Not all of the same services are available as easily in that environment, and for now there's no way to specify plugins as part of the tsc configuration, but figuring out some way to have the same errors would be extremely valuable.

Feature request: require custom elements be registered on HTMLElementTagNameMap

A pass that would diagnose when a custom element is recognized in source code but it hasn't be declared on the HTMLElementTagNameMap, or if it is declared with the wrong tag name. For example:

Warns:

import {customElement, LitElement} from 'lit-element';
@customElement('foo-bar')
class FooBar extends LitElement {}
//    ~~~~~~  warning!

Warns:

import {customElement, LitElement} from 'lit-element';
@customElement('foo-bar')
class FooBar extends LitElement {}

declare global {
  interface HTMLElementTagNameMap {
    'fizz-buzz': FooBar;
//  ~~~~~~~~~~~ warning!
  }
}

Does not warn:

import {customElement, LitElement} from 'lit-element';
@customElement('foo-bar')
class FooBar extends LitElement {}

declare global {
  interface HTMLElementTagNameMap {
    'foo-bar': FooBar;
  }
}

lit-html type checking doesn't detect unmatched closing tag

If I have an unclosed opening tag it detects the error correctly.

    return html`
      <div>
    `;

error TS2322: [lit] This tag isn't closed.

But if I have an unmatched closing tag, no error is reported.

    return html`
      </div>
    `;

My VSCode lit-plugin extension doesn't detect it. But it would be something good to warn for.

TypeError: Cannot read property 'kind' of undefined

TypeScript version: 3.5.1 & 3.6.3
(lit-analyzer has no --version btw)
lit-analyzer version: 1.1.8

When I run it against any file in the Home Assistant Polymer repo, I get this error:

TypeError: Cannot read property 'kind' of undefined
    at isDeclarationNameOrImportPropertyName (/Users/paulus/dev/hass/home-assistant-polymer/node_modules/typescript/lib/typescript.js:61175:29)
    at getTypeOfNode (/Users/paulus/dev/hass/home-assistant-polymer/node_modules/typescript/lib/typescript.js:58919:17)
    at Object.getTypeAtLocation (/Users/paulus/dev/hass/home-assistant-polymer/node_modules/typescript/lib/typescript.js:31456:31)
    at /Users/paulus/dev/hass/home-assistant-polymer/node_modules/ts-simple-type/lib/index.cjs.js:593:55
    at Array.map (<anonymous>)
    at toSimpleTypeInternal (/Users/paulus/dev/hass/home-assistant-polymer/node_modules/ts-simple-type/lib/index.cjs.js:590:59)
    at toSimpleTypeInternalCaching (/Users/paulus/dev/hass/home-assistant-polymer/node_modules/ts-simple-type/lib/index.cjs.js:351:33)
    at /Users/paulus/dev/hass/home-assistant-polymer/node_modules/ts-simple-type/lib/index.cjs.js:593:19
    at Array.map (<anonymous>)
    at toSimpleTypeInternal (/Users/paulus/dev/hass/home-assistant-polymer/node_modules/ts-simple-type/lib/index.cjs.js:590:59)

I went ahead and put a console.log(name) there to see which name has a parent which is undefined and traced it back to this file:

https://www.unpkg.com/@types/[email protected]/cast.framework.d.ts

That file is imported here (although I don't think that matters)

I tried creating a repro by just npm install typescript lit-analyzer @types/chromecast-caf-receiver but was unable to reproduce it. I might give creating repro another stab when I have time.

Feature request: fail on unset required property

I seem to recall lit-analyzer used to have the concept of a "required property" which was defined as a property whose type did not include undefined which was not set with an initializer. There was a rule that would diagnose when an element was used from a template without setting a required property.

Is that rule still around? If it was removed was that because of unforseen issues, or would it be a good candidate for re-adding / reimplementing?

Add support for "@ts-ignore" comments

Opt out of any checking of nodes if there is a leading "@ts-ignore" comment. This is relevant in both inside html and typescript code.

Example 1:
This would make this plugin op out of any checking inside the html template tag.

// @ts-ignore
html`<my-element></my-element>`;

Example 2:
This would make this plugin op out of any checking the div tag.

return html`
  <h1>Hello</h1>

  <!-- @ts-ignore -->
  <div>
      <my-element></my-element>
  </div>
`;

Suggested code fix: Please use the `ifDefined` directive.

The following typescript code would result in the error: Type 'string | undefined' is not assignable to 'string'.

const src = "image.jpg" as string | undefined;
html`<img src="${src}" />`

In this case the plugin should remove undefined from the union string | undefined and test if the result is assignable to string. If the test is successfully the the plugin should suggest using the ifDefined directive. If accepting the code fix, the code will now look like this:

const src = "image.jpg" as string | undefined;
html`<img src="${ifDefined(src)}" />`

[analyzer] Support for intersection types in tag name map

This is fairly low priority as it's a rare pattern that's easily fixed, but filing just so I have a place to point to if it comes up again. A couple of times I've seen code like:

declare global {
  interface HTMLElementTagNameMap {
    'some-element': HTMLElement & {opened: boolean};
  }
}

html`
  <some-element .opened=${true}></some-element>
`;

It seems like the lit-analyzer doesn't understand the intersection type, and reports errors in the html tag.

Intersection type support

First off, I'm very excited by this plugin, excellent work!

I've ran into a small issue relating to union types.

interface ComplexType {
	bool: Boolean;
}
type UnionType = ComplexType & { foo: string };
const complex: ComplexType = { bool: true };
const union: UnionType = { foo: "bah", bool: false };
const unionFunc = () => {
	return union;
};

// create a template which uses these properties
const template = html`<my-foo .complexProperty=${complex} .unionProperty=${union}></my-foo>`;

This errors on the unionProperty assignment with Type 'UnionType' is not assignable to 'UnionType' lit-plugin(2322) which is a thoroughly confusing error :-)

The complex type seems to validate correctly. Am I missing something?

If I pass the result of the unionFunc as .unionProperty=${unionFunc()} I still get the same unxpected error.

Interestingly if I pass the unionFunc as .unionProperty=${unionFunc} then I get no error, which is not what I'd expect since this is a function being assigned to a property, although this may be related to #3.

Make it possible to define custom elements using custom functions

Right now the parser tries to find elements defined using customElements.define and the lit element decorator @customElement. However custom elements can be setup in many other ways (an example could be function-element ).

lit-plugin should at least be able to find these tag names. Parsing components other than lit-element and custom elements is a bit more difficult and I'm not sure if it's out of scope for this project.

Suggestion

Maybe we could introduce a configuration to this plugin (eg customElementFunctions) in order to expand how custom elements can be defined. It could also be a jsdoc tag (on the "define-function") instead, but I think this would be more CPU heavy, because then we would have to scan all functions for this jsdoc tag.

We could come up with a way to define these definition functions with a string where {{tagName}} matches the tag name and {{declaration}} would match a declaration (like the class). Examples:

  • customElements.define({{tagName}}, {{declaration}}) would match customElements.define("my-element", MyElement).
  • @defineElement({{tagName}}) would match a decorator called @defineElement("example-element").
  • @Component({ selector: {{tagName}} }) would match a decorator called @Component({selector: "my-element"})

Feature Request: Notify when custom property overrides prop on native HTMLElement

Hello, it would be helpful if analyzer could notify you (perhaps a dismissible warning?) that you are defining a property that is already defined on HTMLElement. Use Case:

@customElement('my-dialog')
class MyDialog extends BaseElement {
  @query('#primary-button') primaryButton!: HTMLButtonElement;
  @property({type: String}) propDefinedOnBaseElement = 'new default val';
  @property({type: String}) title = 'Default Title'; // warning here

  // lit-analyzer:disable-next-line
  focus() {
    const primaryButton = this.primaryButton;
    if (primaryButton) {
      primaryButton.focus();
    }
  }

  connectedCallback() {
    super.connectedCallback();
    ...
  }

  methodDefinedOnBaseElement() {
    ...
  }

  render() {
    return html`
      <div id="scrim"></div>
      <div id="dialog-container">
        <div id="title">${this.title}</div>
        <div id="content">
          <slot></slot>
        </div>
        <div id="action-buttons">
          <button>Cancel</button>
          <button id="primary-button">Ok</button>
        </div>
      </div>`;
  }
}

In this example, we it would be helpful for there to be a warning when we define title as this both sets the title, yet clashes with HTMLElement.prototype.title, but it doesn't error since they are both strings. This has the unfortunate side-effect where a tooltip is shown wherever you mouseover the dialog.

At the same time, we would not want a warning for the focus method as this is something necessary to override.

Additionally, we would probably not want a warning on methodDefinedOnBaseElement or propDefinedOnBaseElement as they may actually require an override as well as connectedCallback which is native but may also require an override.

Or, perhaps you would want a warning on this, as some teams may have a really-complex inheritance system and they would not like to accidentally override a custom property? It's definitely a case-by-case basis on the custom properties, but I think less so when it comes to props on HTMLElement

Organising rules into individual modules

As part of giving this analyzer a go, i've been reading through the sources and what not.

One thing you could do IMO to tidy things up a lot and make the code base much easier to follow is introduce rules as their own concepts/modules.

What I mean is:

  • Move all "rules" into their own file as functions which follow a new RuleModule type and are used like factories to create a RuleVisitor or some such thing
  • Move all "reports" to the analyzer context
  • Refactor the "analyzers" (e.g. LitHtmlDocumentAnalyzer) to instead load an array of rules and visit each node via them

I've already done most of this in a branch to see what would happen. So if you agree its a fair idea, ill push a PR up at some point when i get it all out of my head.

Support await import when detecting available components

Right now this plugin doesn't detect components used by await import. This should be changed to have the same effect as a normal "import" statement so that any await import in the file makes the components imported available in the entire file.

Screenshot 2019-03-11 at 14 07 57

Type checking with security sanitization in place

When running in an environment with https://github.com/WICG/trusted-types* the types of some security sensitive built-in attributes and properties are effectively changed. For example, an iframe's src isn't string, but TrustedUrl.

Full list of overrides here: https://wicg.github.io/trusted-types/dist/spec/#enforcement-in-sinks

As the spec isn't yet finalized, the types aren't yet included automatically in the main typings. Further, inside google we use a slightly different system for the time being based on closure library types (e.g. https://google.github.io/closure-library/api/goog.html.SafeUrl.html).

Type typing these with these types doesn't have to be perfect, the canonical security layer is at runtime.

*or when running lit-html with lit/lit#750 enabled, which is kinda-sorta a ponyfill of the trusted types spec purely for lit-html templates

Improvements coming to lit-analyzer

Here is an update on what I'm working on at the moment, and which improvement I plan on adding to lit-analyzer. Feel free to add your feedback if you have any features/improvement you really want to see come to this project :-)

During the last couple of weeks I've been working intensely on improving web-component-analyzer (read more in this issue: runem/web-component-analyzer#125)

I've been focusing on these areas:

  • Improve performance
  • Improve JSDoc support and analyzing non-typescript code.
  • Make LitElement-specific metadata available to lit-analyzer
  • Better support for mixins
  • Better component member merging
  • Options to extend HTMLElement with members using TS-typings

Next week I will be turning my focus to lit-analyzer. The update to WCA makes quite a bit possible here:

  • Much better performance (we don't have to analyze every element upfront because this is now lazy. We only have to discover all tag names upfront)
  • It's now possible to add full support for refactoring tag names, events names, attributes and property-names.
  • It's now possible to add more LitElement-specific rules such as "this private member should probably have {attribute: false}"
  • WCA now analyzes private and protected members (previously it just skipped them), making it possible to run LitElement-specific rules on private members as well ๐ŸŽ‰
  • WCA now outputs parts (using the jsdoc tag @csspart), making it possible to autocomplete parts in CSS.
  • WCA now analyzes methods, opening the possible to analyze if a call to eg. super.connectedCallback is missing somewhere in the chain.

I will also be taking a look at the following features:

  • Experimental support for libraries containing a "custom-element.json" file
  • Better support for checking which elements are available in a given file (by following imports). In addition, I'm thinking about adding a rule that makes it possible to catch when importing unused elements. In my own code I always forget to remove unused imports when I'm no longer using a specific element anymore.

Thanks for reading through this update. Again, feel free to add your feedback if you have any features/improvement that you really want to see come to this project ๐Ÿ‘

Make it possible to extend the component analyzer with custom logic

~/lit-analyzer/packages/vscode-lit-plugin [master|โœš 1] 
00:40 $ npm i

> [email protected] postinstall /Users/mantou/lit-analyzer/packages/vscode-lit-plugin/node_modules/lit-html
> node ./node_modules/vscode/bin/install

internal/modules/cjs/loader.js:626
    throw err;
    ^

Error: Cannot find module '/Users/mantou/lit-analyzer/packages/vscode-lit-plugin/node_modules/lit-html/node_modules/vscode/bin/install'

There is also a type error in file ~/lit-analyzer/packages/vscode-lit-plugin/src/extension.ts:
Screen Shot 2019-12-10 at 01 14 58

Thank you for providing such a useful tool.
I now want to add a custom command to my own library.

False positive errors in CSS bindings

A binding like this:

html`
  <style>
    :host {
      transform-origin: ${x}% ${y}%;
    }
  </style>
`;

Gives this error on the semi-colon on the transform-origin line:

term expectedlit-plugin(2322)

Support generic html<T>`...` tagged template literal

Hi.

I'm using a generic html tagged template literal function in a project, which isn't currently picked up by your plugin.

Is this something you'd consider supporting?

More info...

Having a generic template literal function can be useful in advanced scenarios where you'd like to type-check the values passed to the literal are of a certain type.

Here's a minimal example. My actual usecase involves a complicated custom type, but here I'm just setting the type as string...

function html<V>(
  literals: readonly string[],
  ...values: Array<V>
) {
// implementation
}

// lit-plugin recognises this:
const template = html`<h1 class="example">Hello ${"World"}</h1>`;

// but this isn't recognised but lit-plugin (so no syntax highlighting, code completion, etc)
const template = html<string>`<h1 class="example">Hello ${"World"}</h1>`;

Is this something your plugin could recognise in future?

Thanks for the great plugin by the way!

Mike

PS...

I've tried adding html<string> to "lit-plugin.htmlTemplateTags" in settings but it didn't help (and would be a pain to update for different types in any case).

"lit-plugin.htmlTemplateTags": [
        "html",
        "raw",
        "html<string>"
    ],

<input> value and other properties should accept more types

Right now a binding like:

html`<input type="range" .value=${currentValue} .max=${max}>`;

Will report errors on the value and max bindings if currentValue and max are numbers. But an input handles this just fine. This may be something that needs to be updated in the typings, but maybe there's something to be done in the plugin?

Auto completion for `string unions` and `enums` attribute values

It will make sense show all possible values for string union and enum attribute types when asking for auto completions in the attribute assignment of the html.

<input type=">>> right here <<<" />
<!-- Here it would suggest: "text", "email", "date", ... -->
<my-button size=">>> right here <<<" />
<!-- Here it would for example suggest: "small", "medium" and "large" -->

These suggestions should only be shown when there is not already an expression inside the value of the attribute.

Surprising error message for extra characters around non-string bindings

We chatted about this issue in the comments of #21 but it turns out I never filed a bug on it.

Consider code with (surprisingly common!) typos like:

html`
<button @tap=${handler}" >
<button ?disabled=${handler}} >
`

In both cases there's an extra character after the binding which the user probably didn't intend, but which causes a somewhat confusing error message, as lit-analyzer thinks that we're passing a string to something that should be some other type. This is double confusing because it will usually do the right thing at runtime.

Add type checking when using lit-html directives

Because directives are functions that take a Part and can transform the value these are difficult to type check. We can improve the developer experience by doing extra type checking when using these builtin directives and opting out when using custom directives.

This issue only focuses on checking attribute directives.

Read more about directives here: https://lit-html.polymer-project.org/guide/template-reference#built-in-directives

classMap

If the "classMap" directive is used, make sure that the attribute value assigned doesn't contain multiple expression, but only one single expression. Only do this check on the "class" attribute assignment and report error if this directive is being used with other attribute names.

This is valid

html`<div class=${classMap(classes)}>Classy text</div>`;

This is not valid

html`<div class="someClass ${classMap(moreClasses)}">Broken div</div>`;

styleMap

If the "styleMap" directive is used, make sure that the attribute value assigned doesn't contain multiple expression, but only one single expression. Only do this check on the "style" attribute assignment and report error if this directive is being used with other attribute names.

This is valid

html`<p style="${styleMap(style)}">Hello style!</p>`;

This is not valid

html`<p style="color: red; ${styleMap(style)}">Hello style!</p>`;

ifDefined

If the "ifDefined" directive is used in an attribute assignment with only one single expression, do the following check when checking the type. Remove undefined from the type union (if possible) and test if this result is now assignable to the attribute type.

html`<img src="${ifDefined(imageUrl)}">`;

guard

If the "guard" directive is used in an attribute assignment check if the return value type of the expression given to the second parameter is assignable to the attribute.

html`<img src="${guard([imageUrl], () => Math.random() > 0.5 ? imageUrl : "nothing.png")}">`;

unsafeHTML / cache / repeat / asyncReplace / asyncAppend

unsafeHTML, cache, repeat, asyncReplace and asyncAppend can only be used within a text binding. Therefore report errors if this directive is used in any other binding.

html`<div>${unsafeHTML("<h1>Hello</h1>")}</div>`;

All other directives

Make sure that the function is a directive function (it must be of type (part: Part) => void), and opt out any checking for the relevant attribute assignment.

Dynamically Define an Attribute on HTMLElement

Description

Hello, I'm currently writing a component that needs to search for an identifying attribute in the light DOM. e.g.

<mwc-dialog>
  <div>
	This is my content!!!
	Here is an input that should be focused when opened:
	<input mdc-dialog-initial-focus>
  </div>
  <button
	  slot="primaryAction"
	  mdc-dialog-action="close">
	Close dialog
  </button>
</mwc-dialog>

Problem

The problem is that lit-analyzer will warn that mdc-dialog-inital-focus is not defined on input. Though, I'd only like to define this attribute if mwc-dialog is imported.

Expected

Trying to figure out how this would work, I was attempting the following to try to remedy this, but it didn't seem to work

Using global interfaces

declare global {
  interface HTMLElement {
    "mdc-dialog-action": string;
    "mdc-dialog-initial-focus": boolean;
  }
}

...
html`<div mdc-dialog-inital-focus></div>`

expected no warning on either and possible even autocompletion with lit-plugin in vscode.

Result

There is a warning on those attributes

Workaround-ish

Trying to hack web-component-analyzer

/**
 * @element div
 * @attr mdc-dialog-action
 * @attr mdc-dialog-initial-focus
 */

/**
 * @element input
 * @attr mdc-dialog-action
 * @attr mdc-dialog-initial-focus
 */

/**
 * @element button
 * @attr mdc-dialog-action
 * @attr mdc-dialog-initial-focus
 */

...
// etc. but it doesn't work for custom-elements

Rollup necessity?

out of interest, is there a reason you use rollup?

why not just build directly using tsc with CJS/ES2015+ as a target? (which would work fine in node)?

Allow "null" and "undefined" as values always when using "?" attr binding

The "?" attribute binding only sets the attribute if the value is truthy. Therefore using undefined and null is valid in this case and this shouldn't result in an error.

Screenshot 2019-04-13 at 22 25 03

The type accepted when using the "boolean" attribute binding should be null | undefined | boolean.

Note: Consider if it's better to allow any type when using the "?" instead.

Config for disable plugin in components without decorators

What a wonderful job you are doing here! This idea is amazing, and it was the main feature I was missing as I came from a React background. Description and import checks are LOVE. Thank you guys very much.

Please correct me if I am wrong, but what I understand is that this plugin will not work well with lit-elements without decorators. Am I right? So, if I use a <my-button> element that has a property message declared with static get properties(), the linter will scream if I try to use <my button message="message">:

// my-button.js
import { LitElement, html } from 'lit-element';

class MyButton extends LitElement {
  constructor() {
    super();

    this.message = '';
  }

  static get properties() {
    return {
      message: { type: String },
    };
  }

  render() {
    return html`
      <button>${this.message}</button>
    `;
  }
}
// Register the element with the browser
customElements.define('my-button', MyButton);
// my-app.js

import { LitElement, html } from 'lit-element';
import "./my-button";

export class MyApp extends LitElement {
  render() {
    return html`<my-button message="adasda"></my-button>`;
<!--                       |-------- This will scream 'Unkown atribute "message"' -->
  }
}

customElements.define('my-app', MyApp);

Am I doing something wrong? If not, is there any way to not check attributes in case that a lit-element has no property decorator? A lot of times we use third-party components and in that case, we can't control if the class will have a decorator or not.

Thank you guys, again. You are amazing.

border shorthand css error

I'm not sure if this is a valid linter error, but we are getting these whenever we try to use a color in border shorthand:

const color = css`#eee`;
const styles = css`
  .something {
    border: 2px solid ${color};
  }
`;

We're getting 'semi-colon expected' error at the first 'c' in color on line 4.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.