Overview

Mates re-exports common lit-html directives from the mates package so you do not need a separate lit-html import. Use them in the binding positions they support (classMap in class=, ifDefined in attribute position, etc.).

For dynamic inline styles, prefer the Mates element directive style({…}) (see /docs/directives/attr-style) over stringly style= interpolation. lit-html’s cache directive is exported as litCache to avoid clashing with other cache APIs in Mates.

lit-html vs Mates element directives

Directive
Kind
Notes
classMap lit — class= Use as class=${classMap({…})}.
classes Mates — element Use as ${classes({…})} inside the tag. See class-style.
style() Mates — element Property map with conditional tuples — not lit-html styleMap.
litCache lit — cache Re-exported as litCache (lit-html cache).

Directives: ifDefined, classMap

Directives are special values you embed in html`` expressions. classMap accepts plain objects and efficiently applies only the classes that changed. ifDefined removes an attribute entirely when the value is undefined.

import { html, atom, renderApp, classMap, ifDefined } from 'mates';

const App = () => {
const active = atom(false);
const size = atom(16);
const tooltip = atom('');

return () => html`
<div class="m-col m-gap">
<!-- classMap — toggle classes based on object -->
<div class=${classMap({
'card': true,
'btn-primary': active(),
})} >
<p class="m-0">This card uses <code>classMap</code></p>
</div>

<!-- Inline styles: use mates style() — see /docs/directives/attr-style -->
<div class="${active() ? 'font-active' : 'font-inactive'}" style="font-size:${size()}px">
Dynamic font size: ${size()}px
</div>

<!-- ifDefined — only sets attribute when defined -->
<button
title=${ifDefined(tooltip() || undefined)}
class="m-self-start"
>
${tooltip() ? 'Hover for tooltip' : 'No tooltip (empty)'}
</button>

<div class="m-flex m-items-center m-justify-center m-gap-sm">
<button @click=${() => active.set(v => !v)}>
Toggle active
</button>
<input type="range" min="12" max="32" .value=${size()}
@input=${e => size.set(+e.target.value)} title="Font size" />

live() for drifted inputs

live(value) forces the property write every render — useful when the DOM may diverge from the bound value (e.g. user-edited inputs reset from state).

import { html, atom, live, renderApp } from 'mates';

const App = () => {
const value = atom('Ada');
return () => html`
<div class="m-col m-gap">
<input .value=${live(value())}
@input=${(e) => value.set(e.target.value)} />
<button @click=${() => value.set('Ada')}>Reset</button>
<p class="muted m-t-5">${value()}</p>
</div>
`;
};
renderApp(App, document.getElementById('app'));