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.