Creating directives
createDirective turns a function receiving an element into a fragment that can be interpolated inside an opening tag. Wrap it in an outer function to create a directive that takes configuration — the outer function is ordinary JavaScript, with parameters and closures like any other.
const className = (value: string) =>
createDirective((node) => {
node.classList.add(value);
});
const Notice = () => html`<p ${className('notice')}>Saved</p>`;Directives compose by appearing together on the same element, and each one owns its own setup and cleanup independently. They're the right tool once behavior needs a browser API a template attribute can't express — an event listener with its own cleanup, for instance, rather than something you could just write as a static class.
selectOnFocus in main.ts has the right shape but its handler is empty. Add a focus listener to input that calls input.select(), and return a cleanup function that removes the listener.
Reveal solution
import { createDirective, html, mount } from '@grainular/nord';
const selectOnFocus = createDirective<HTMLInputElement>((input) => {
const select = () => input.select();
input.addEventListener('focus', select);
return () => input.removeEventListener('focus', select);
});
const App = () => html`
<main>
<h1>Custom directives</h1>
<p>Click into the field — its value should select automatically.</p>
<input ${selectOnFocus} type="text" value="Copy me" />
</main>
`;
mount(App, { to: document.querySelector('#app') });Move on to conditional rendering for control flow that updates only the active branch.