Overview

onConnect(cb) fires after the decorated element is connected to the live DOM. onDisconnect(cb) fires when it is removed. Both receive the element as the first argument.

focusOnMount(options?) focuses the host on the next macrotask (setTimeout of 0) so the node is committed first. It has no onUpdate, so a re-render does not focus again. If the element disconnects before that turn, the timeout is cleared.

disappear(ms) removes the host after ms milliseconds. Unmount cancels the timer. A changed ms on re-render starts a fresh countdown.

Element directives vs component hooks

API
Scope
Notes
onConnect / onDisconnect Per element Element directives on a single node in the template.
onMount / onCleanup Per component Outer-function hooks for the whole component lifetime. See /docs/lifecycle/on-mount.
focusOnMount / disappear Per element focusOnMount focuses once after mount. disappear removes the node after a delay.
eleHook Full imperative Mount + onUpdate + onCleanup when you need ongoing sync.

Element connect / disconnect log

onConnect fires after the element is appended to the live DOM tree; onDisconnect fires just before it is removed. Both receive the element itself as the first argument.

import { html, atom, onConnect, onDisconnect, nothing, renderApp } from 'mates';

const App = () => {
const show = atom(true);
const log = atom([]);
const addLog = (msg) => log.set(prev => [msg, ...prev].slice(0, 6));

return () => html`
<div class="m-col m-gap">
<button @click=${() => show.set(v => !v)}>
${show() ? 'Remove' : 'Add'} element
</button>
${show() ? html`
<div
class="card card-body"
${onConnect(el => addLog('✓ Element connected to DOM'))}
${onDisconnect(el => addLog('✗ Element removed from DOM'))}
>
This element fires onConnect / onDisconnect
</div>
` : nothing}
<div class="card card-body">
<span class="overline">Lifecycle log</span>
${log().length === 0
? html`<div class="mono subtle">Toggle the element…</div>`
: log().map(e => html`<div class="mono">${e}</div>`)
}
</div>
</div>
`;
};
renderApp(App, document.getElementById('app'));

focusOnMount

Focus runs on the next macrotask after mount. Toggling the atom remounts the input and focuses it. Updating a sibling atom does not.

import { html, atom, focusOnMount, nothing, renderApp } from 'mates';

const App = () => {
const show = atom(true);
const ticks = atom(0);
return () => html`
<div class="m-col m-gap">
<button @click=${() => show.set(v => !v)}>Toggle input</button>
<button @click=${() => ticks.set(n => n + 1)}>Re-render (${ticks()})</button>
${show()
? html`<input ${focusOnMount()} placeholder="Focused after mount" />`
: nothing}
</div>
`;
};
renderApp(App, document.getElementById('app'));

disappear

The host is removed from the DOM after the delay. Unmounting the parent first cancels the timer.

import { html, atom, disappear, keyed, nothing, renderApp } from 'mates';

const App = () => {
const n = atom(0);
return () => html`
<div class="m-col m-gap">
<button @click=${() => n.set(v => v + 1)}>Show message</button>
${n()
? keyed(n(), html`<p class="label" ${disappear(1500)}>Saved (${n()})</p>`)
: nothing}
</div>
`;
};
renderApp(App, document.getElementById('app'));