Defining Functionality Defining your components behavior and exposed properties package Guide
Categories

Defining Functionality

The createComponent callback defines the behaviors of your component when creating a component. These behaviors can be accessed from various locations that might need to reference or invoke them.

For instance you might need to invoke a behavior from:

Creating Instances

Create Component

The createComponent callback defines your component instance and its methods.

const defaultState = { counter: 0 };
const createComponent = ({self, state, settings}) => ({
setCounter(number) {
state.counter.set(number);
},
startCounter() {
state.running.set(true);
self.interval = setInterval(() => state.counter.increment(), 1000);
},
stopCounter() {
state.running.set(false);
clearInterval(self.interval);
},
});

You can access other data like settings, state, as well as the DOM using $ and $$ from inside your component instance, allowing you to manipulate data from the DOM, access sources of reactivity, and settings passed through to your component.

For more information see component lifecycle.

Accessing Instances

From Lifecycle Callbacks

Component instances are passed through to all other callbacks as self allowing you to reference methods and values directly from events, key bindings, and lifecycle callbacks.

Lifecycle

const onRendered = ({ self, isClient }) => {
if(isClient) {
self.draw();
}
});

Keybindings

const keys = {
'f'({ self }) {
self.search();
}
}

From Events

const events = {
'click .start'({ self }) {
self.startCounter();
},
'click .stop'({ self }) {
self.stopCounter();
}
}

”Self” Aliases

Component callbacks provide additional aliases for self that your team may prefer to use.

aliaswhy use
tpltpl is short for template instance and is a shorter, albeit idiosyncratic keyword than self
componentcomponent provides more clarity than self but is a bit more verbose

For consistency the documentation will use self but these aliases can be used interchangeably

const events = {
'click .start'({ tpl }) {
tpl.startCounter();
},
'click .stop'({ component }) {
component.stopCounter();
}
}

In Templates

Your template’s data context can be used to access values from your component instance directly.

Templates

<p>Your name is {getName}</p>

Accordion Example

The following example shows using self to access behaviors from inside event handlers, and when iterating through sections from the template.

From Other Components

Component instances can be directly accessed from other components to access properties and methods directly.

findParent

The most common scenario will require you to access some functionality on a parent template instance from a sub template or a nested web component.

The findParent helper can be used in this scenario, allowing you to walk up the render tree looking for a component matching the specified name.

const createComponent = ({ findParent }) => {
getTodos() => {
const todoList = findParent('todo-list');
return todoList.todos;
}
};

findChild / findChildren

You can use findChild and findChildren to look down the render tree for any subtemplates that match a given component name

const createComponent = ({ findChildren }) => {
getRowName(id) => {
const tableRows = findChildren('table-rows');
const row = tableRows.filter(row => row.id == id);
return row.name;
}
};

findTemplate

If you need to access an arbitrary template from any other template you can use findTemplate

const createComponent = ({ findTemplate }) => {
getTodos() => {
const component = findTemplate('sibling-component');
return component.someMethod();
}
};

From DOM

You can access your template instance directly from the DOM to modify its internal state, or access values.

Each component instance stores its values and is accessible from the DOM as el.component.

You can use Query’s component() helper to easily access a component instance

With Query

import { $ } from '@semantic-ui/query';
const counter = $('ui-counter').component();
counter.setCounter(2);

With Pure JS

const { component } = document.querySelector('ui-counter');
component.setCounter(2);

Storage in the DOM Your template instance is stored as el.component i.e. el.component.getName() instead of directly as properties on your web component element i.e el.getName(). This is to isolate it from unrelated code, making it easier to inspect, clone and disambiguate from the many internal DOM properties which are not under your control.

DOM Access Example

In this example the external input on the page updates the internal reactive state of the web component, preventing the counter from running when the external input is focused.

You can view this interaction in index.js.

Previous
Creating
Next
Lifecycle