@controller
decoratorCatalyst's @controller
decorator lets you create Custom Elements with virtually no boilerplate, by automatically calling customElements.register
, and by adding "Actions" and "Targets" features described later. Using TypeScript (with decorators
support enabled), simply add @controller
to the top of your class:
import {controller} from '@github/catalyst'
@controller
class HelloWorldElement extends HTMLElement {
connectedCallback() {
this.innerHTML = 'Hello World!'
}
}
Catalyst will automatically convert the classes name; removing the trailing Element
suffix and lowercasing all capital letters, separating them with a dash.
By convention Catalyst controllers end in Element
; Catalyst will omit this when generating a tag name. The Element
suffix is not required - just convention. All examples in this guide use Element
suffixed names.
Remember! A class name must include at least two CamelCased words (not including the Element
suffix). One-word elements will raise exceptions. Example of good names: UserListElement
, SubTaskElement
, PagerContainerElement
@controller
do?The @controller
decorator ties together the various other decorators within Catalyst, plus a few extra conveniences such as automatically registering the element, which saves you writing some boilerplate that you'd otherwise have to write by hand. Specifically the @controller
decorator:
Element
suffix and lowercasing all capital letters, separating them with a dash.window.customElements.define
with the newly derived tag name and your class.defineObservedAttributes
with the class to add map any @attr
decorators. See attrs for more on this.connectedCallback()
function of your class:
bind(this)
; ensures that as your element connects it picks up any data-action
handlers. See actions for more on this.autoShadowRoot(this)
; ensures that your element loads any data-shadowroot
templates. See rendering for more on this.initializeAttrs(this)
; ensures that your element binds any data-*
attributes to props. See attrs for more on this.You can do all of this manually; for example here's the above HelloWorldElement
, written without the @controller
annotation:
import {bind, autoShadowRoot, initializeAttrs, defineObservedAttributes} from '@github/catalyst'
class HelloWorldElement extends HTMLElement {
connectedCallback() {
autoShadowRoot(this)
initializeAttrs(this)
this.innerHTML = 'Hello World!'
bind(this)
}
}
defineObservedAttributes(HelloWorldElement)
window.customElements.define('hello-world', HelloWorldElement)
The @controller
decorator saves on having to write this boilerplate for each element.
If you don't want to use TypeScript decorators, you can use controller
as a regular function by passing it to your class:
import {controller} from '@github/catalyst'
controller(
class HelloWorldElement extends HTMLElement {
//...
}
)