p-elements-core
v2.1.5
Published
P Elements Core V2
Downloads
2,746
Readme
P-Element
CustomElement base class
Static properties
projectorMode "append", "merge" or "replace"
The projector mode when using templateFromString function
style string
The style is adopted to the rootNode.
if this is set there is no need for calling templateFromString. A root node is created and replaced with the result of the render function.
example
class MyElement extends CustomElement {
static style = `
:host {
color: red;
}`;
render = () :VNode {
return <div>Hello world</div>;
}
}isFormAssociated boolean
If true, elementInternals are created using attachInternals in the constructor.
example
class MyElement extends CustomElement {
static isFormAssociated = true;
@property({type: "string", attribute: "value", reflect: true })
value: string = "Peter" ;
updated(property: string, oldValue: any, newValue: any) {
if (property === "value"){
this.internals.setFormValue(this.value);
}
}
render = () :VNode {
return <div>Hello {this.value}.</div>;
}
}Decorators
@CustomElementConfig
Use this decorator to define the custom element
example
@CustomElementConfig({
tagName: "p-foo",
})
class PFooElement extends CustomElement {
...
}If you want to extend a build in component you need to specify the buildin.
example
@CustomElementConfig({
tagName: "super-a",
options: {
extends: "a",
},
})
class SuperAnchorElement extends HTMLAnchorElement {
...
}@property
Use the @property decorator to define reactive properties.
example
@CustomElementConfig({
tagName: "p-foo",
})
class PFooElement extends CustomElement {
...
@property({type: "string", attribute: "nick-name", reflect: true})
nickName: string;
attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
super.attributeChangedCallback(name, oldValue, newValue);
...
}The type option could be "string", "number", "boolean" or "object".
If attribute option is set the property will be set on attribute change. If you implement a attributeChangeCallback you need to call the super.attributeChangedCallback.
If reflect is true the attribute is set on property change.
Use converter option to convert attribute to property
const stringArrayConverter: AttributeConverter<string[]> = {
fromAttribute: (value) => {
if (!value) {
return null;
}
return value.split(",").map((v) => v.trim());
},
toAttribute: (value) => {
if (!value.join) {
return null;
}
return value.join(",");
},
};
class MyElement extend CustomElement {
@property({attribute: "items", reflect: true, converter: stringArrayConverter})
items: string[] = ["foo", "bar"];
}@query decorator
Use the @query decorator to define a property that returns an element from the shadow dom.
example
class PFooElement extends CustomElement {
...
@query("#MyInput")
nameInput: HTMLInputElement;
render = () => {
return <div>
<label for="MyInput"></label>
<input type="text" id="MyInput" />
</div>;
}
}@propertyRenderOnSet @renderOnSet
Properties decorated with @propertyRenderOnSet or @renderOnSet call renderNow when setting a value.
example
class PFooElement extends CustomElement {
...
@propertyRenderOnSet
public foo: string = "foo";
}@bind
(deprecated, use arrow function myFn = () => console.log('myFn'))
Functions decorated with @bind will be replaced with the result of bind(this) on the function.
CustomElementController
The CustomElementController is an abstract base class that allows you to create reusable controllers that can be attached to custom elements. Controllers have access to the host element's lifecycle and can trigger renders.
Creating a Controller
Controllers must extend the CustomElementController class and can implement the ICustomElementController interface methods:
import { CustomElementController, CustomElement } from 'p-elements-core';
class MyController extends CustomElementController {
// Called when the controller is initialized
init?(): void {
console.log('Controller initialized');
}
// Called when the host element connects to the DOM
connected?(): void {
console.log('Host connected');
}
// Called when the host element disconnects from the DOM
disconnected?(): void {
console.log('Host disconnected');
}
// Called before the host element renders
hostRenderStart?(): void {
console.log('Host render starting');
}
// Called after the host element finishes rendering
hostRenderDone?(): void {
console.log('Host render done');
}
}Using a Controller
Create an instance of your controller in the custom element constructor or init method, passing the host element:
@CustomElementConfig({
tagName: "my-element",
})
class MyElement extends CustomElement {
private myController: MyController;
init() {
this.myController = new MyController(this);
}
render = () => {
return <div>Element with controller</div>;
}
}The controller is automatically registered with the host element when constructed.
Controller Methods
Controllers have access to the following methods:
renderNow(): Triggers an immediate render of the host elementscheduleRender(): Schedules a render of the host elementhostElement: Property that returns the host custom element
Example: Timer Controller
class TimerController extends CustomElementController {
private intervalId?: number;
connected() {
this.intervalId = window.setInterval(() => {
console.log('Timer tick');
this.scheduleRender(); // Update the host element
}, 1000);
}
disconnected() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
}
}Hooks
init
The init is the first function called after initialising of the custom element
shouldUpdate
Before a property is set to a new value
updated
After a property value is set to a new value
renderStart
When the custom element start the rendering
renderDone
When the custom element is finished rendering
attributeChangedCallback
Call super.attributeChangedCallback() first.
CustomElementController
The CustomElementController is an abstract base class that allows you to create reusable controllers that can be attached to custom elements. Controllers have access to the host element's lifecycle and can trigger renders.
Creating a Controller
Controllers must extend the CustomElementController class and can implement the ICustomElementController interface methods:
import { CustomElementController, CustomElement } from 'p-elements-core';
class MyController extends CustomElementController {
// Called when the controller is initialized
init?(): void {
console.log('Controller initialized');
}
// Called when the host element connects to the DOM
connected?(): void {
console.log('Host connected');
}
// Called when the host element disconnects from the DOM
disconnected?(): void {
console.log('Host disconnected');
}
// Called before the host element renders
hostRenderStart?(): void {
console.log('Host render starting');
}
// Called after the host element finishes rendering
hostRenderDone?(): void {
console.log('Host render done');
}
}Using a Controller
Create an instance of your controller in the custom element constructor or init method, passing the host element:
@CustomElementConfig({
tagName: "my-element",
})
class MyElement extends CustomElement {
private myController: MyController;
init() {
this.myController = new MyController(this);
}
render = () => {
return <div>Element with controller</div>;
}
}The controller is automatically registered with the host element when constructed.
Controller Methods
Controllers have access to the following methods:
renderNow(): Triggers an immediate render of the host elementscheduleRender(): Schedules a render of the host elementhostElement: Property that returns the host custom element
Example: Timer Controller
class TimerController extends CustomElementController {
private intervalId?: number;
connected() {
this.intervalId = window.setInterval(() => {
console.log('Timer tick');
this.scheduleRender(); // Update the host element
}, 1000);
}
disconnected() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
}
}