Manual HTML Directives

Directives

elements man html/directives Read as markdown

The e:-prefixed attributes: e:for, e:if / e:elseif / e:else, and e:switch / e:case / e:default.

Directives are e:-prefixed attributes. They compose with normal attributes on the same element. On an element with both e:if and e:for, the e:if is evaluated first: a false e:if means the element does not render at all, and a true e:if allows e:for to iterate.

e:for

Iterates over any iterable. The result is reactive: updates patch the DOM in place at the row level.

<li e:for={user of users}>{user.name}</li>
<li e:for={[index, user] of users.entries()}>{index}: {user.name}</li>
<li e:for={key in lookup}>{key}: {lookup[key]}</li>

for...of and for...in work the same as in JavaScript: of iterates arrays and other iterables; in iterates object keys, string characters, and similar. The Elements runtime patches for...of at the row level. for...in re-renders the whole list when the right side changes.

By default rows are keyed by the id field on each item. Provide an id and the runtime diffs by it, patching only the rows that changed. Without an id, rows key by object identity, so replacing the array with fresh objects (say, a refetch) re-renders every row.

Use e:key to supply your own key function when a row has no id, or when the stable key isn't a field on the row, such as iterating Object.entries, composite keys, and so on. It takes the iteration value and returns a string or number:

<li e:for={[index, item] of Object.entries(items)} e:key={([index, item]) => item.id}>
  {index} - {item.description}
</li>

The key function's parameter is the e:for iteration value, typed the same as the loop binding, so a wrong destructure or a missing field is a compile error. e:key pairs with e:for on the same element (either order).

e:if / e:elseif / e:else

<div e:if={status === "loading"}>loading</div>
<div e:elseif={status === "error"}>error: {error.message}</div>
<div e:else>ready</div>

Branches must be siblings. Whitespace between them is allowed.

e:switch / e:case / e:default

Parent holds the expression, children are cases.

<div e:switch={status}>
  <span e:case="active">active</span>
  <span e:case="paused">paused</span>
  <span e:default>unknown</span>
</div>