Home > Software engineering >  How do you extend Shoelace web component in Typescript using Lit
How do you extend Shoelace web component in Typescript using Lit

Time:03-21

After extending <sl-button> component in Lit, I am not getting Typescript errors for the wrong attributes being passed. For example, in the code snippet below, when I call <sl-button> with the wrong attribute typescript shows errors, but if I call <my-button> with the wrong attribute typescript doesn't show any error.

import SlButton from '@shoelace-style/shoelace/dist/components/button/button.js';
import {html} from 'lit';
import {customElement} from 'lit/decorators.js';

@customElement('my-button')
export default class MyButton extends SlButton {
  constructor() {
    super();
  }
}

export const Demo = () =>
  html`
    <my-button size="not-exists">Click here!</my-button> // shows no error on "size"
    <sl-button size="not-exists">Click here!</sl-button> // shows error on "size"
  `;

declare global {
  interface HTMLElementTagNameMap {
    'my-button': MyButton;
  }
}

CodePudding user response:

This appears to be working as expected. I believe what you're looking for isn't a TypeScript error, as TS doesn't care about HTML attributes, but code completion for your editor.

I suspect you're using VS Code with the custom data provided by Shoelace. This is what tells VS Code about registered Shoelace elements, and if you open up dist/vscode.html-custom-data.json you'll see each tag and a list of available attributes.

If you're extending and re-tagging Shoelace elements, you'll need to provide your own custom data to VS Code.


A couple notes:

First, when you import components/button/button.js, you're still registering a Shoelace button. In fact, your code is registering both <sl-button> and <my-button> because registration happens on import.

Second, Shoelace components aren't built to be renamed. Many rely on tag names for things to work, such as <sl-menu> which expects children to be <sl-menu-item> and <sl-tab-group> which expects <sl-tab> and <sl-tab-panel> children. Renaming them will break things in unexpected ways.

  • Related