question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[lit-element] Declarative event emitters

See original GitHub issue

It would be convenient for ergonomics, documentation, React integration, and transpilers to be able to declare what events an element fires.

We could add a decorator (and static block for plain JS, like properties) that allows this by decorating event handler properties. The decorator would create accessors that use addEventListener under the hood.

TypeScript:

class MyElement extends LitElement {
  @event() onFoo!: (e: FooEvent) => any) | null;

  render() {
    html`<button @click=${this._onButtonClick}>Click Me</button>`;
  }

  _onButtonClick(e) {
    this.dispatchEvent(new FooEvent());
  }
}

interface HTMLElementEventMap {
  'foo': FooEvent;
}

JavaScript:

class MyElement extends LitElement {
  static events = {
    onFoo: {},
  };

  render() {
    html`<button @click=${this._onButtonClick}>Click Me</button>`;
  }

  _onButtonClick(e) {
    this.dispatchEvent(new FooEvent());
  }
}

See some similar previous discussion here: https://github.com/Polymer/lit-element/issues/808

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:11
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
daKmoRcommented, Feb 12, 2020

many questions 😬 😅
how is onFoo connected to _onButtonClick or _onButtonClick? what would users of the component do? <my-element @onFoo=${}>?

0reactions
landritocommented, Dec 11, 2020

To tie this back to the original proposal:

class MyElement extends LitElement {
  @event() onFoo!: (e: FooEvent) => any) | null;

  render() {
    html`<button @click=${this._onButtonClick}>Click Me</button>`;
  }

  _onButtonClick(e) {
    this.dispatchEvent(new FooEvent());
  }
}

interface HTMLElementEventMap {
  'foo': FooEvent;
}

The interface HTMLElementEventMap above is unnecessary for Events with string literal types for their type field. Assume FooEvent is declared as follows:

class FooEvent extends Event {
  readonly type!: 'foo';

  constructor() {
    super('foo');
  }
}

Furthermore I’d propose that the Decorator Options provided are specific to the Event in question. For example, the opts @ChristianUlbrich provided above could be updated to:

export type EventName<E extends Event | void = void> =
  E extends {type: infer TypeAttribute} ? TypeAttribute : string;

export interface EventOptions<E extends Event | void = void> {
  /**
   * A string custom event name to override the default.
   */
  eventName?: EventName<E>
}

const opts: EventOptions<FooEvent> = {
  // Expected Error: Type '"Bar"' is not assignable to type '"foo" | undefined'.
  eventName: 'Bar'
}

There is a problem though. Typescript doesn’t seem to support generic decorators very well meaning the type of the decorators target is not propagated to the decorator function: https://github.com/microsoft/TypeScript/issues/2607.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Events - Lit.dev
Declarative event listeners are added when the template is rendered. This is usually the best way to add listeners to elements in your...
Read more >
[lit-element] Declarative event emitters · Issue #3277 - GitHub
It would be convenient for ergonomics, documentation, React integration, and transpilers to be able to declare what events an element fires.
Read more >
How to Handle Events with LitElement and TypeScript
This will allow capturing the click event. In other words, we're adding an event listener in a declarative way. Let's assume the brand...
Read more >
How to handle and pass events to the lit component from ...
handleEvent}" in html template and handle the function handleEvent(e){} inside the lit Element component. By this the events are limited and ...
Read more >
Using Event Decorators with lit-element and Web Components
Learn how to make an event decorator to make it easy to emit custom events with improved type safety in Lit Web Components....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found