What goos is an application if you can't interact with it? In Palette, events are handled using native HTML events and Custom Events.
Palette Components being HTML elements means they have the .dispatchEvent()
method which allows for dispatching a custom event:
define("my-button", {
template: html`<button>Click me</button>`,
script() {
this.listen("button", "click", () => {
this.dispatchEvent(new CustomEvent("my-clicked-button-event"));
})
}
})
In the above example, were listening for clicks and then firing a custom event. This works fine, but is a contrived example. UI events still work as usual from within Palette Components, so you can just let the browser handle event firing for simple components with interactive elements.
For example, consider a "fancy-button" element which just provides some styles and themes to a standard button tag. A component using the fancy-button in its own template could just listen for click events on the component.
To streamline firing events, Palette components also offer an alternate
signature for this.dispatchEvent():
define("my-button", {
template: html`<button>Click me</button>`,
script() {
this.listen("button", "click", () => {
// Shorthand for `new CustomEvent("my-clicked-button-event");
this.dispatchEvent("my-clicked-button-event");
});
this.listen("button", "dblclick", () => {
// Include custom event options (detail/bubbles/etc)
this.dispatchEvent("another-event", { detail: "double!" });
});
}
})
When dispatching an event using the shorthand signature, the default values for custom event options are tuned for the majority use case:
{
bubbles: true,
cancelable: true,
composed: true,
detail: undefined
}
Palette Components offer a .listen() helper function to set up event listeners
which are automatically cleaned up when the component unmounts.
The .listen() method takes a target descriptor, event name, and handler.
define("my-component", {
template: html`
<div>
<input id="name-input" type="text" />
<button>Submit</button>
</div>
`,
script() {
// Listen for "input" events from the element with the ID "name-input"
this.listen("#name-input", "input", (event) => {
console.log(`The name is ${event.target.value}`);
});
// Listen for click events on any button in the template
this.listen("button", "click", (event) => {
console.log("Submitting!");
});
// Add a listener for the host element for the component, rather than for
// an element within the template
this.listen(":host", "mouseenter", () => {
console.log("Hello, mouse!");
})
}
})
Target descriptors for listen() may be a CSS selector, a Component class, or
an explicit HTML element reference.