@joystick.js/ui

Render

How to use the render() method on a Joystick component.

The only required option on a Joystick component is the render() method. The render() method is defined as a function that returns a string of HTML using a JavaScript template literal (enables usage of multi-line strings in JavaScript as well as interpolation of variables and function calls).

The render() method receives a single argument: the entire component instance as an object. In addition to the built-in properties and functions on the instance, Joystick also introduces a series of "render methods:" functions that can be used within your HTML to do things like embed another component, loop over a list of items, or load a translation.

Rendering HTML

The simplest Joystick component just renders a string of HTML. Joystick components do not utilize attribute hacks or domain-specific syntax that are common in other frameworks. If the HTML you're using is defined in the HTML spec, it will work with Joystick—no exceptions.

ui/pages/index/index.js

import joystick from '@joystick.js/ui';

const Index = joystick.component({
  render: () => {
    return `
      <div class="index">
        <p>This is the index page. You can render any HTML you wish here.</p>
      </div>
    `;
  },
});

export default Index;

Render Methods

One of the more powerful features of a Joystick component are render methods. Render methods are functions passed to your component's render() method that provide additional functionality for things like rendering other components, looping over lists, or rendering a translation tag.

component()

The component() method helps you to render another component within the current component.

Example Usage

ui/layouts/app/index.js

import joystick from '@joystick.js/ui';
import Player from '../../components/player/index.js';

const App = joystick.component({
  state: {
    player: null,
  },
  lifecycle: {
    ... 
  },
  render: ({ component, props, state }) => {
    return `
      <div class="app">
        ${component(props.page, props)}
        ${component(Player, { state: state?.player })}
      </div>
    `;
  },
});

export default App;

Here, inside of a layout component, we use the component() render method (destructured from the component instance passed to the render() method) twice: first, to render the props.page component we've been passed, and second, an example Player component.

In addition to the component we'd like to render, we can also pass props down to it. This makes it easy to share state between parent and children components.

API

Definition
component(component: object, props: object) => html
Parameters
component object required
The component you'd like to render.
props object
Any props you'd like to pass down to the component being rendered.

each()

The each() method helps you to loop over an array of elements.

Example Usage

ui/layouts/app/index.js

import joystick from '@joystick.js/ui';

const Books = joystick.component({
  render: ({ each, props }) => {
    return `
      <div class="books">
        <ul>
          ${each(props?.books, (book = {}) => {
            return `<li>${book.title} by ${book.author}</li>`;
          })}
        </ul>
      </div>
    `;
  },
});

export default Books;

Here, we have a component Books that we want to render a list of books passed to us via props. We use the each() render method (destructured from the component instance passed to the render() method) to render the props.books list.

API

Definition
each(value: array, callback: function) => html
Parameters
value array required
The array of elements you'd like to render.
callback function
A callback function returning the HTML you'd like to render for each element.

i18n()

The i18n() method helps you to render a translation string.

Example Usage

ui/layouts/app/index.js

import joystick from '@joystick.js/ui';

const DashboardHeader = joystick.component({
  render: ({ i18n, props }) => {
    return `
      <div class="dashboard-header">
        <h1>${i18n('dashboard_header.hey', { name: props.username })}</h1>
      </div>
    `;
  },
});

export default DashboardHeader;

Here, we have a component DashboardHeader where we render a translation at the key dashboard_header.hey (in our translation file) into our HTML. Additionally, we anticipate our translation having a replacement {{name}} inside of it, passing props.username as a value.

Learn About Translations

Joystick's translations feature makes it easy to define translations in any language and load them into your UI with a simple function.

API

Definition
i18n(translation_path: string, replacements: object) => html
Parameters
translation_path string required
The path to the translation you'd like to render in your translation file.
replacements object
Values for any replacements inside of your translation.

when()

The when() method helps you to conditionally render HTML.

Example Usage

ui/layouts/app/index.js

import joystick from '@joystick.js/ui';

const App = joystick.component({
  render: ({ when, props }) => {
    return `
      <div class="profile">
        ${when(props?.user?.is_admin, () => `
          <nav class="admin-navigation">...</nav>
        `)}
        ${when(!props?.user?.is_admin, () => `
          <nav class="user-navigation">...</nav>
        `)}
      </div>
    `;
  },
});

export default App;

Here, we have a layout component App where we render different navigation based on whether or not the props?.user?.is_admin value is true. Though we've passed a function returning a template literal string here, when() also accepts a template literal string without a wrapper function.

API

Definition
when(value: boolean, html: <function -> string|string>) => html
Parameters
value boolean required
The boolean value to test to decide whether or not the conditional HTML should be rendered.
html function|string
Either a plain template literal string, or, a function returning a template literal string containing the HTML you'd like to render conditionally.