- ClayJS
- Reference
- Setup
- Satellites
Satellites
The separate libraries — clay-ui, clay-events, clay-options, clay-dom, all.js, clay-utils, clay-data, sap.js — one script tag each.
Satellites are the separate libraries beside the core: each is its own library with its own script tag and docs, and like clayjs they are HTML-first with no build step.
Bring them in when the problem shows up#
These aren’t checkboxes; bring them in when the problem shows up. Each loads as a plain <script>. To call one from an inline script right after its tag, wait for it first: await clay.loaded.ui (or .dom, .all, .utils, .events, .options, .data, .sap).
clay-ui.js#
Ready-made toasts, modals, and ask/confirm/tell dialogs. It listens to clay:save-* events automatically, so adding it upgrades your save feedback for free: a failed or offline save shows a toast that stays up until the next save succeeds, and Saved shows as a toast only when the indicator chip is not loaded. If you already have a toast library, keep yours: the events are public. Set clay.saveToast = true (or window.clay = { saveToast: true } before clayjs loads) to show Saved as a toast, with the host’s message, instead of on the chip.
<script src="https://clayjs.com/v1/clay-ui.js"></script>
clay.toast(message, type)—success(default),info,warningorerror; gone on click or after about 6.6 s.clay.toastPersistent(message, type)stays until closed.clay.ask(prompt, onYes, defaultValue, extraHtml),clay.confirm(prompt, onYes, extraHtml),clay.tell(title, ...paragraphs)andclay.snippet(title, code, extraHtml)— the prompt is the dialog’s title, and Enter confirms. Ask, confirm and tell return a promise that resolves on OK or Confirm (ask with the typed text) and rejects on Cancel, close or Escape; anonYesthat throws keeps the dialog open and toasts the error. Snippet’s promise resolves when it closes.clay.modal— the dialog they are built on. Settitle,html,yes,no(markup or a node each),closeHtml(any non-empty value shows the close button) andwidth(default600px), registeronYes(fn)/onNo(fn), thenopen(). Every setting resets after the modal closes.
clay-events.js#
HTML attributes for the events HTML forgot: onclickaway, onclickchildren, onrender, onmutation, onglobalmutation (alias onpagemutation), onclone.
<script src="https://clayjs.com/v1/clay-events.js"></script>
A mutation handler that writes into what it watches runs forever, even when it writes the same text: guard it, if (this.textContent !== n) this.textContent = n.
clay-options.js#
Declarative show/hide: an ancestor carries a state attribute (view="kanban"), descendants opt in or out with show-when:view (alias option:view), hide-when:view or option-not:view. Any ancestor matches, not only the nearest.
<script src="https://clayjs.com/v1/clay-options.js"></script>
clay-dom.js#
Small prototype helpers for DOM-first apps: el.nearest.menu, el.val.title, el.exec.action() (getter proxies reading the nearest element with that attribute or class; “nearest” searches siblings and cousins too, so in a list it can reach a neighbouring record), and el.cycleAttr(1, "data-status"), which sets the attribute to the next value used anywhere in the document, in alphabetical order. el.cycle(order, attr) is different: it replaces the element with a copy of another element carrying attr. clay.dom.createContentView(root, {capability}) returns an inert view of a subtree with a region capability filtered out (data drops no-data and editor-ui); clay.dom.cleanContentClone(node, opts) returns one cleaned clone.
<script src="https://clayjs.com/v1/clay-dom.js"></script>
all.js#
A chainable wrapper over querySelectorAll, All(".card").css({ opacity: 1 }).onclick(e => …); the full form is All(".card").css({ opacity: 1 }).onclick(e => e.target.classList.toggle("done")). Events are property-form (.onclick, .oninput); classes go through .classList. Zero dependencies, one script tag.
<script src="https://clayjs.com/v1/all.js"></script>
clay-utils.js#
The small stuff: throttle, debounce, cookie.get / cookie.remove, slugify, copyToClipboard.
<script src="https://clayjs.com/v1/clay-utils.js"></script>
hyper-morph exported#
The content-based DOM morphing that powers live sync ships inside the sync plugin and is exported as clay.morph. Use it to update a page in place while preserving focus, inputs, and animations. JSON script tags marked merge="name" are three-way merged per key during sync instead of overwritten.
clay.Mutation exported#
The shared mutation hub that autosave and live sync sit on. clay.Mutation.onAnyChange(opts, cb) respects clay="no-watch" regions so your observers and clayjs’s agree about what counts as a change.
clay-data.js#
The live page as JSON. clay.extractData(rules?) reads the live DOM. clay.applyData(values, {rules}) validates the complete change, then changes the live DOM atomically. It writes content only. Scripts, styles, event handlers, executable URLs, innerHTML, outerHTML, and unknown keys are refused without a partial change. Load it with await clay.loaded.data.
<script src="https://clayjs.com/v1/clay-data.js"></script>
Core adds the saved file operations beside that satellite. await clay.readData(rules?) returns {data, etag}. await clay.writeData(values, {rules, ifMatch}) returns {data, etag} after the corresponding sync frame has reached the live page. All four methods use the page’s api rules tag when rules are omitted. Explicit rules are sent as the URL encoded JSON data query on the document’s own path.
writeData always sends If-Match, using the supplied value or the page’s current save version. It does not retry a 412, adopt the JSON response’s ETag as the page save version, or send while the page is dirty, saving, conflicted, held, or disconnected from live sync. It holds automatic and manual saves until the incoming file update is applied, then replays any save requested during the hold. A successful write whose sync frame does not arrive within 12 seconds resolves with {data, etag, pageUpdatePending: true, message}. The write has landed in that case, so callers must not retry it automatically. Server failures reject with an Error carrying status, error, message, and details.
sap.js#
Reactive templates with the DOM itself as the state: attributes and elements are the source of truth, templates re-render when the DOM they depend on changes. No virtual DOM, no store. Its core (records and paints) loads by itself as the derive plugin; this tag adds the rest and takes the page over (see Derived values).
clay-internals.js#
The pieces clayjs builds itself out of, for code that sits inside the save lifecycle.