@fundamental-engine/react 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zach Shallbetter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # @fundamental-engine/react
2
+
3
+ **The React adapter for [`@fundamental-engine/core`](../core)** — a reciprocal DOM-physics field as a React
4
+ component. Elements you mark with `data-body` become forces; the single background field reacts to
5
+ them, and its density reacts back. You author meaning in JSX (`data-*` in); the field returns
6
+ measurement (`--field-*` CSS variables out).
7
+
8
+ → Live manual, Lab, and gallery at **[fundamental-engine.com](https://fundamental-engine.com)**.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npm i @fundamental-engine/react
14
+ ```
15
+
16
+ React (17, 18, or 19) is a **peer dependency** — the core engine itself stays zero-dependency.
17
+
18
+ ## Use
19
+
20
+ ```tsx
21
+ import { FieldField } from '@fundamental-engine/react';
22
+
23
+ export function App() {
24
+ return (
25
+ <>
26
+ <FieldField accent="#4da3ff" />
27
+ <a data-body="attract" data-strength="0.9" data-range="320" data-feedback>
28
+ pull me
29
+ </a>
30
+ </>
31
+ );
32
+ }
33
+ ```
34
+
35
+ `<FieldField>` mounts a fixed, full-viewport canvas behind your app and runs the engine on it — the
36
+ same field the `<field-root>` custom element and vanilla `mountField()` wrap. The field reacts to every
37
+ `[data-body]` element on the page (the *field-reacts* law), so the bodies do not need to be children of
38
+ `<FieldField>`.
39
+
40
+ ## Props
41
+
42
+ `<FieldField>` accepts every [`FieldOptions`](../core) value plus React conveniences:
43
+
44
+ | Prop | Type | What it does |
45
+ |---|---|---|
46
+ | `accent` | `string` | base hue for the field (any CSS color) |
47
+ | `density` | `number` | particle density multiplier |
48
+ | `render` | `'dots' \| 'trails' \| 'links' \| 'metaballs' \| 'voronoi' \| 'streamlines'` | underlay render method |
49
+ | `palette` | `string \| string[]` | named palette (`ours`, `heatmap`, `infrared`, `spectrum`) or explicit colors |
50
+ | `waves` | `boolean` | enable wave propagation |
51
+ | `mass` | `boolean` | first-class mass in the integrator |
52
+ | `attention` | `boolean` | attention/importance weighting |
53
+ | `causality` | `boolean` | causal-trail visualization |
54
+ | `heatmap` | `boolean` | density heatmap diagnostic |
55
+ | `className` / `style` | — | applied to the managed `<canvas>` |
56
+ | `onReady` | `(field: FieldHandle) => void` | called once the engine is live |
57
+
58
+ ```tsx
59
+ <FieldField
60
+ render="streamlines"
61
+ palette="infrared"
62
+ onReady={(field) => field.setFormation('wells')}
63
+ />
64
+ ```
65
+
66
+ ## Driving the field from code
67
+
68
+ `onReady` hands you the live `FieldHandle` — the full imperative surface:
69
+
70
+ ```tsx
71
+ <FieldField onReady={(field) => {
72
+ field.scan(); // re-pick-up [data-body] elements after a render
73
+ field.setFormation('wells');
74
+ field.setRender('trails');
75
+ field.burst(window.innerWidth / 2, 200); // a one-off impulse
76
+ field.flowTo(x, y); // a movable focus the field bends toward
77
+ }} />
78
+ ```
79
+
80
+ | Method | Use |
81
+ |---|---|
82
+ | `scan()` / `rescan()` | re-read `[data-body]` elements after the DOM changes |
83
+ | `setAccent(hex)` · `setPalette(p)` | recolor live |
84
+ | `setFormation(name)` | arrange particles into a named formation (e.g. `wells`) |
85
+ | `setRender(mode)` · `setOverlay(mode)` | change the underlay / overlay surface |
86
+ | `setAttention(on)` · `setCausality(on)` · `setHeatmap(on)` | toggle diagnostics |
87
+ | `burst(x, y, hex?)` · `flowTo(x, y)` · `clearFlow()` | impulses and a movable focus |
88
+ | `destroy()` | stop the loop and remove the managed canvas |
89
+
90
+ ### The hook
91
+
92
+ For full control of the canvas element yourself, use `useFieldField()` instead of the component:
93
+
94
+ ```tsx
95
+ const { canvasRef, fieldRef } = useFieldField({ accent: '#4da3ff' });
96
+ return <canvas ref={canvasRef} className="my-field" />;
97
+ // fieldRef.current is the FieldHandle once mounted
98
+ ```
99
+
100
+ ## Marking bodies — the `data-body` vocabulary
101
+
102
+ Any element on the page becomes a *body* by carrying `data-body`. The common attributes:
103
+
104
+ | Attribute | Meaning |
105
+ |---|---|
106
+ | `data-body="attract"` | the force token (`attract`, `gravity`, `charge`, `sink`, …) |
107
+ | `data-strength` | how hard it bends the field |
108
+ | `data-range` | radius of influence, in px |
109
+ | `data-feedback` | opt in to receiving `--field-*` variables back |
110
+ | `data-absorb` / `data-max` | for `sink` bodies: accretion load and capacity |
111
+
112
+ After rendering **new** bodies, call `field.scan()` (e.g. from `onReady` or via `fieldRef`) so the
113
+ engine picks them up.
114
+
115
+ ## Server-side rendering (Next.js, Remix, Astro islands)
116
+
117
+ The field is a browser effect — the engine starts inside React effects, so `<FieldField>` is safe to
118
+ include in an app that server-renders, but it only comes alive on the client. In the Next.js App
119
+ Router, render it from a Client Component (`'use client'`).
120
+
121
+ ## Recipes & data binding
122
+
123
+ To apply a named recipe or bind data to the field, use `applyRecipe()` / `bindData()` from
124
+ [`@fundamental-engine/platform`](../platform) against a ref'd container. Browse all 64 recipes at
125
+ [`/docs/gallery`](https://fundamental-engine.com/docs/gallery).
126
+
127
+ ## Aliases
128
+
129
+ `ForcesField` / `useForcesField` and `ForcesFieldProps` are deprecated aliases of `FieldField` /
130
+ `useFieldField` / `FieldFieldProps`, kept for the `forces-ui` → `field-ui` rename.
131
+
132
+ ## Related
133
+
134
+ [`@fundamental-engine/core`](../core) · [`@fundamental-engine/platform`](../platform) · [`@fundamental-engine/elements`](../elements)
135
+ · [`@fundamental-engine/vanilla`](../vanilla) · the [documentation map](../../docs/README.md).
136
+
137
+ ## License
138
+
139
+ MIT © Zach Shallbetter
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The React adapter (Phase 7) — `<FieldField>` mounts the reciprocal field on a
3
+ * canvas via the core engine, the same field the custom element and `mountField`
4
+ * wrap. React is a peer dependency (the one framework dep; the core stays zero-dep).
5
+ *
6
+ * ```tsx
7
+ * import { FieldField } from '@fundamental-engine/react';
8
+ * <FieldField accent="#4da3ff" /> // a full-viewport reciprocal field
9
+ * <FieldField onReady={(f) => f.scan()} /> // grab the handle to drive it
10
+ * ```
11
+ *
12
+ * The field reacts to `[data-body]` elements anywhere on the page (the field-reacts
13
+ * law); call `field.scan()` from `onReady` after you render new bodies.
14
+ */
15
+ import type { CSSProperties, ReactElement, RefObject } from 'react';
16
+ import { type FieldHandle, type FieldOptions } from '@fundamental-engine/core';
17
+ export interface FieldFieldProps extends FieldOptions {
18
+ className?: string;
19
+ style?: CSSProperties;
20
+ /** called once the field is created, with its handle (scan/burst/setAccent/…). */
21
+ onReady?: (field: FieldHandle) => void;
22
+ }
23
+ export declare function FieldField({ className, style, onReady, accent, density, waves, background, render, overlay, mass, palette, attention, causality, }: FieldFieldProps): ReactElement;
24
+ /**
25
+ * Hook form — returns a ref to attach to your own `<canvas>` and the live handle.
26
+ * Use when you need to own the canvas element (sizing, placement) yourself.
27
+ */
28
+ export declare function useFieldField(opts?: FieldOptions): {
29
+ canvasRef: RefObject<HTMLCanvasElement | null>;
30
+ fieldRef: RefObject<FieldHandle | null>;
31
+ };
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAsB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAqB,MAAM,0BAA0B,CAAC;AAGtH,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,kFAAkF;IAClF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAGxC;AAKD,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,KAAK,EACL,OAAO,EACP,MAAM,EACN,OAAO,EACP,KAAK,EACL,UAAU,EACV,MAAM,EACN,OAAO,EACP,IAAI,EACJ,OAAO,EACP,SAAS,EACT,SAAS,GACV,EAAE,eAAe,GAAG,YAAY,CAwChC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,YAAiB,GAAG;IACtD,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,QAAQ,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACzC,CAmCA"}
package/dist/index.js ADDED
@@ -0,0 +1,96 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * The React adapter (Phase 7) — `<FieldField>` mounts the reciprocal field on a
4
+ * canvas via the core engine, the same field the custom element and `mountField`
5
+ * wrap. React is a peer dependency (the one framework dep; the core stays zero-dep).
6
+ *
7
+ * ```tsx
8
+ * import { FieldField } from '@fundamental-engine/react';
9
+ * <FieldField accent="#4da3ff" /> // a full-viewport reciprocal field
10
+ * <FieldField onReady={(f) => f.scan()} /> // grab the handle to drive it
11
+ * ```
12
+ *
13
+ * The field reacts to `[data-body]` elements anywhere on the page (the field-reacts
14
+ * law); call `field.scan()` from `onReady` after you render new bodies.
15
+ */
16
+ import { useEffect, useRef } from 'react';
17
+ import { FIELD_CANVAS_STYLE } from '@fundamental-engine/core';
18
+ import { createBrowserField } from '@fundamental-engine/platform';
19
+ // the fixed, click-through surface — shared with the vanilla mount via core/surface.ts.
20
+ const FIXED = FIELD_CANVAS_STYLE;
21
+ export function FieldField({ className, style, onReady, accent, density, waves, background, render, overlay, mass, palette, attention, causality, }) {
22
+ const canvasRef = useRef(null);
23
+ const onReadyRef = useRef(onReady);
24
+ onReadyRef.current = onReady;
25
+ /** Field Surfaces: the front overlay surface this component owns, lazily created. */
26
+ const overlayCanvasRef = useRef(null);
27
+ useEffect(() => {
28
+ const canvas = canvasRef.current;
29
+ if (!canvas)
30
+ return;
31
+ // Field Surfaces: lazily create the overlay canvas the first time an overlay is set.
32
+ // Matches the element's pattern: fixed, full-viewport, click-through, above content.
33
+ if (overlay !== undefined && overlay !== 'off' && !overlayCanvasRef.current && typeof document !== 'undefined') {
34
+ const oc = document.createElement('canvas');
35
+ oc.setAttribute('aria-hidden', 'true');
36
+ oc.style.cssText =
37
+ 'position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:5;mix-blend-mode:screen';
38
+ document.body.appendChild(oc);
39
+ overlayCanvasRef.current = oc;
40
+ }
41
+ const field = createBrowserField(canvas, {
42
+ accent, density, waves, background, render,
43
+ overlay, overlayCanvas: overlayCanvasRef.current ?? undefined,
44
+ mass, palette, attention, causality,
45
+ });
46
+ onReadyRef.current?.(field);
47
+ return () => {
48
+ field.destroy();
49
+ // Field Surfaces: remove the overlay canvas this component owns on teardown.
50
+ overlayCanvasRef.current?.remove();
51
+ overlayCanvasRef.current = null;
52
+ };
53
+ // re-create only when an engine option actually changes
54
+ }, [accent, density, waves, background, render, overlay, mass, palette, attention, causality]);
55
+ return (_jsx("canvas", { ref: canvasRef, "aria-hidden": "true", className: className, style: { ...FIXED, ...style } }));
56
+ }
57
+ /**
58
+ * Hook form — returns a ref to attach to your own `<canvas>` and the live handle.
59
+ * Use when you need to own the canvas element (sizing, placement) yourself.
60
+ */
61
+ export function useFieldField(opts = {}) {
62
+ const canvasRef = useRef(null);
63
+ const fieldRef = useRef(null);
64
+ /** Field Surfaces: the front overlay surface this hook owns, lazily created. */
65
+ const overlayCanvasRef = useRef(null);
66
+ const { accent, density, waves, background, render, overlay, mass, palette, attention, causality } = opts;
67
+ useEffect(() => {
68
+ const canvas = canvasRef.current;
69
+ if (!canvas)
70
+ return;
71
+ // Field Surfaces: lazily create the overlay canvas when an overlay reading is requested.
72
+ if (overlay !== undefined && overlay !== 'off' && !overlayCanvasRef.current && typeof document !== 'undefined') {
73
+ const oc = document.createElement('canvas');
74
+ oc.setAttribute('aria-hidden', 'true');
75
+ oc.style.cssText =
76
+ 'position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:5;mix-blend-mode:screen';
77
+ document.body.appendChild(oc);
78
+ overlayCanvasRef.current = oc;
79
+ }
80
+ const field = createBrowserField(canvas, {
81
+ accent, density, waves, background, render,
82
+ overlay, overlayCanvas: overlayCanvasRef.current ?? undefined,
83
+ mass, palette, attention, causality,
84
+ });
85
+ fieldRef.current = field;
86
+ return () => {
87
+ field.destroy();
88
+ fieldRef.current = null;
89
+ // Field Surfaces: remove the overlay canvas this hook owns on teardown.
90
+ overlayCanvasRef.current?.remove();
91
+ overlayCanvasRef.current = null;
92
+ };
93
+ }, [accent, density, waves, background, render, overlay, mass, palette, attention, causality]);
94
+ return { canvasRef, fieldRef };
95
+ }
96
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@fundamental-engine/react",
3
+ "version": "0.4.0",
4
+ "description": "React adapter for Fundamental — a reciprocal DOM-physics field as a <FieldField> component + useFieldField hook.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Zach Shallbetter <hi@zachshallbetter.com> (https://zachshallbetter.com)",
8
+ "homepage": "https://fundamental-engine.com",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/zachshallbetter/fundamental-engine.git",
12
+ "directory": "packages/react"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/zachshallbetter/fundamental-engine/issues"
16
+ },
17
+ "keywords": [
18
+ "Fundamental",
19
+ "react",
20
+ "particles",
21
+ "physics",
22
+ "canvas",
23
+ "field",
24
+ "react-component"
25
+ ],
26
+ "sideEffects": false,
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "main": "./dist/index.js",
33
+ "types": "./dist/index.d.ts",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.js"
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "dependencies": {
48
+ "@fundamental-engine/platform": "0.4.0",
49
+ "@fundamental-engine/core": "0.4.0"
50
+ },
51
+ "peerDependencies": {
52
+ "react": ">=18"
53
+ },
54
+ "devDependencies": {
55
+ "@types/react": "^19.0.0",
56
+ "react": "^19.0.0",
57
+ "typescript": "^5.9.3"
58
+ },
59
+ "scripts": {
60
+ "build": "tsc -p tsconfig.json",
61
+ "typecheck": "tsc -p tsconfig.json --noEmit",
62
+ "test": "node --test"
63
+ }
64
+ }