Guides
The web component
<field-root> is the keystone — a custom element that drops into any
framework (or plain HTML) unchanged. "Every element is a body" is a web-components-shaped
idea.
Install
npm i @field-ui/elements Set up the field
Import the package once to register the element, then drop a single
<field-root> anywhere. It mounts a fixed, full-viewport canvas behind
your page and runs the engine. It's decorative, so it marks itself
aria-hidden automatically.
<script type="module">
import '@field-ui/elements';
</script>
<field-root accent="#4da3ff"></field-root> Mark elements as bodies
The field reacts to every [data-body] element on the page (the field-reacts
law). Forces compose, space-separated; each force reads only the attributes it uses.
<!-- one force -->
<a data-body="attract" data-strength="0.9" data-range="320">pull me</a>
<!-- composed forces + a condition gate + density write-back -->
<button
data-body="repel swirl"
data-strength="1.2"
data-range="240"
data-spin="1"
data-when="active"
data-feedback
>swirl</button> [data-body] elements later (a route change, a list update), call
field.scan() so it picks them up.
Attributes
Set these on the <field-root> element:
- accent — the travelling accent colour (a hex string).
- density — particle-count multiplier (default 1).
- waves — draw the background Currents (default on;
"false"to disable). - render —
dots·trails·links·metaballs·voronoi·streamlines. - palette —
ours·heatmap·infrared·spectrum. - attention — opt into conserved attention (one finite strength budget).
- causality — opt into cross-boundary causality (density spills to neighbours).
Full details in the options reference.
Methods
The full FieldHandle is proxied onto the element, so any page can drive the field after it mounts:
const field = document.querySelector('field-root');
field.scan(); // after adding/removing [data-body] elements
field.setFormation('wells'); // global field bias
field.setAttention(true); // conserved attention (one strength budget)
field.setCausality(true); // density spills to neighbours
field.setRender('streamlines'); // draw the force field itself
field.setPalette('heatmap'); // swap the accent colour template
field.burst(x, y, '#fff'); // a one-shot shove + heat near a point The Field Cell
For a small, in-frame, single-force demo (instead of the page-wide field), use
<field-cell> — a container-sized canvas that runs one force with its own
particle pool. It pauses off-screen (IntersectionObserver), re-fits on resize, and honours
reduced motion. It's the embeddable unit behind the Manual's per-concept demos.
<field-cell force="swirl" color="#2dd4bf"></field-cell> attract, repel, swirl, gravity,
stream, buoyancy, and tether. For the full catalog of 34 against the canonical math, use the page field
or the Lab.