shadow
Shadow is a base class inheriting from HTMLElement for Web Components and Custom Elements.
Quick Start
Compile example/my_example.ts
:
deno bundle --config example/tsconfig.json example/my_example.ts > example/my_example.js
Serve the index.html
file:
deno run --allow-net --allow-read https://deno.land/std/http/file_server.ts example/
Print the documented API:
deno doc mod.ts
Example
import {
css,
customElement,
html,
property,
Shadow,
} from "https://deno.land/x/shadow/mod.ts"
@customElement("my-example")
export class MyExample extends Shadow {
@property()
h1Content = 0
@property()
pContent = "some text"
clickHandler(e: MouseEvent) {
return this.h1Content++
}
static styles = css`
h1 {
color: blue;
}
#myButton {
color: green;
}
`
render() {
return html`
<h1 id="heading">${this.h1Content}</h1>
<p>${this.pContent}</p>
<button @id="myButton" click=${this.clickHandler}>Count</button>
`
}
}
API
class Shadow extends HTMLElement
This class is the reason why you are here.
constructor()
connected: boolean
This boolean will be true
when connectedCallback
has been called and all
explicitly awaited properties have been set (the waitingList
is empty).
shadowRoot: ShadowRoot
dom: Dom
The child elements, which match the id and class selectors marked with the @
sign, are stored in the dom
object.
static styles: HTMLTemplateElement[]
The return type of the function css
, which is an array of HTMLTemplateElements
containing a script element, is assigned to this static property.
static is?: string
The decorator customElement
- if used - sets this static property to the
custom element's tag name automatically.
connectedCallback()
A native custom elements'
lifecycle callback.
When you use this callback, you probably want to call
super.connectedCallback()
inside of it.
attributeChangedCallback(name: string, oldValue: Attribute, newValue: Attribute)
A native custom elements' lifecycle callback. Here, it manages the reflecting of properties to attributes.
init(propertiesAndOptions: PropertyAndOptions[]): void
Call this method in 'connectedCallback' if you want to avoid using the 'property' decorator. It assigns the accessors to the element's properties and starts rendering.
update(name: string, newValue: Attribute): void
Reflects properties to attributes.
render?(): AllowedExpressions
Is called by the method actuallyRender
which renders the custom element. It
must return the return type of the function html
which is
AllowedExpressions
.
firstUpdated?(event: Event): void
A modifiable lifecycle callback which is called after the first update which includes rendering.
updated?(event: Event): void
A modifiable lifecycle callback which is called after each update which includes rendering.
function html(strings: TemplateStringsArray, ...values: AllowedExpressions[]) => AllowedExpressions
Uses htm (Hyperscript Tagged Markup) under
the hood which uses standard JavaScript Tagged Templates and works in all modern
browsers. The function html
takes a tagged template and processes the
AllowedExpressions
where false
and null
are converted to an empty string
and the numbers
are stringified. The elements matching the id and class
selectors marked with an @
sign will later be added to the this.dom
object.
We add the EventListeners
with addEventListener(event, listener.bind(this))
so that you don't need to use arrow functions anymore. It parses SVG elements as
well.
function css(strings: TemplateStringsArray, ...values: (string | HTMLTemplateElement)[]): HTMLTemplateElement[]
The css
tag function parses css strings which can contain expressions with the
type string or HTMLTemplateElements (containing a script element).
function customElement(tagName: string): (clazz: Constructor) => void
The customElement
decorator takes the tag name of the custom element and
registers the custom element. The same tag name is assigned to the static is
property.
function property({reflect, render, wait, assert}: Omit<PropertyAndOptions, "property">)
The property
decorator takes an optional object as argument with four optional
properties:
- Setting
reflect
to false would stop the element's attribute from synchronising. - If you don't want the changing of the property to cause a rerendering, then
set
render
to false. - If you plan to use properties instead of attributes as data input, setting
wait
to true would reduce the amount of renderings from 2 to 1 (you can just ignore it). - The
assert
boolean checks if the input has a truthy value.