Skip to content

Building components

Kory Nunn edited this page Jul 16, 2019 · 2 revisions

Three patterns

Where possible, it's generally a good idea to adhere to the state -> render -> event -> state life-cycle, but there are rare exceptions.

The three main component styles are 'generic', 'application', and 'self-contained'

Generic component

Used for non-application-specific components, like buttons, text-boxes etc.

  • Accepts bindings
  • Emits events

Example:

function createTextbox(valueBinding){
    return fastn('input', {
        value: valueBinding
    })
    .on('input', event => this.emit('value', this.element.value));
}

Application component

Used for application-specific components like a loggedInUserCard

  • Attaches to application state
  • Calls application actions

Example:

function createSearchbar(app){
    return fastn('nav',
        fastn('label', 'Search'),
        createTextbox(fastn.binding('search'))
        .on('value', app.setSearch)
    );
)

Usage:

var rootApplicationComponent = fastn('div',
    createSearchbar(app),
    createBookList(app),
    ...
)

Self-contained component

Almost exclusively useful when rendering data-defined UI's, like nodes in an AST.

  • Attaches to state
  • Mutates state

Example:

function createTextNode(nodeDefinition){
    return createTextBox(fastn.binding(nodeDefinition.path))
    .on('value', (event, state) => {
        state.set(nodeDefinition.path, this.element.value)
    })
}