@wave3d/react 0.1.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 Wave Studio contributors
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,52 @@
1
+ # @wave3d/react
2
+
3
+ A drop-in, self-optimizing animated **3D gradient wave** for React — the `<Wave3D>` component.
4
+
5
+ Poster-first and lazy: it renders a server-safe `<div>`, then on the client mounts the wave — showing a poster immediately and upgrading to live WebGL only when the browser can run it (falling back to the poster on no-WebGL, Save-Data, reduced-motion, or context loss), with `three.js` code-split out of the initial load.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add @wave3d/react @wave3d/core three # + @types/three for TypeScript
11
+ ```
12
+
13
+ `react` (`>=18`), `@wave3d/core`, and `three` are peer dependencies.
14
+
15
+ ## Usage
16
+
17
+ ```tsx
18
+ import { Wave3D } from "@wave3d/react";
19
+
20
+ <Wave3D preset="Hero" poster="/wave.png" style={{ width: 480, height: 270 }} />;
21
+ ```
22
+
23
+ Server-render your own poster by passing it as a child — the shell adopts it:
24
+
25
+ ```tsx
26
+ <Wave3D poster="/wave.png">
27
+ <img data-wave3d-poster src="/wave.png" alt="" />
28
+ </Wave3D>
29
+ ```
30
+
31
+ ## Props
32
+
33
+ | Prop | Type | Notes |
34
+ | ------------------------ | ----------------------------------------- | --------------------------------------------------------------------------- |
35
+ | `preset` | `string \| () => Partial<StudioConfig>` | a name (lazy-loads the presets chunk) or a function preset (tree-shakeable) |
36
+ | `config` | `Partial<StudioConfig>` | escape hatch, applied last |
37
+ | `poster` | `string` | poster image shown before / instead of WebGL |
38
+ | `lazy` | `boolean` | defer the upgrade until visible |
39
+ | `webgl` | `"auto" \| "force" \| "off"` | force or disable the WebGL upgrade |
40
+ | `respectReducedMotion` | `boolean` | freeze on the poster for reduced-motion users |
41
+ | `onReady` / `onFallback` | `(renderer) => void` / `(reason) => void` | lifecycle callbacks |
42
+ | `className`, `style` | — | forwarded to the container `<div>` |
43
+
44
+ Plus flat shortcuts mapped onto the first wave / scene: `palette`, `sheen`, `iridescence`, `speed`, `opacity`, `blendMode`, `theme`, `background`, `transparentBackground`, `quality`, `dprMax`, `loopSeconds`, `paused`, and more. Precedence: **default ← preset ← flat props ← `config`**.
45
+
46
+ ## Credits
47
+
48
+ Created by [Amir Abushanab](https://github.com/Amir-Abushanab).
49
+
50
+ ## License
51
+
52
+ [MIT](https://github.com/Amir-Abushanab/wave3d/blob/main/LICENSE)
@@ -0,0 +1,52 @@
1
+ import { CSSProperties, ReactElement, ReactNode } from "react";
2
+ import { BlendMode, ColorStop, FallbackReason, FallbackReason as FallbackReason$1, StudioConfig, StudioConfig as StudioConfig$1, WaveHandle, WaveRenderer, WaveRenderer as WaveRenderer$1 } from "@wave3d/core";
3
+
4
+ //#region src/index.d.ts
5
+ /** Flat props mapped onto the first wave. */
6
+ interface FlatWaveProps {
7
+ palette?: string[] | ColorStop[];
8
+ fiberCount?: number;
9
+ fiberStrength?: number;
10
+ sheen?: number;
11
+ iridescence?: number;
12
+ displaceAmount?: number;
13
+ speed?: number;
14
+ opacity?: number;
15
+ blendMode?: BlendMode;
16
+ theme?: "solid" | "wireframe";
17
+ }
18
+ /** Flat props mapped onto the scene. */
19
+ interface FlatSceneProps {
20
+ background?: string;
21
+ transparentBackground?: boolean;
22
+ quality?: number;
23
+ dprMax?: number;
24
+ loopSeconds?: number;
25
+ introRamp?: boolean;
26
+ paused?: boolean;
27
+ }
28
+ interface Wave3DProps extends FlatWaveProps, FlatSceneProps {
29
+ /** A preset: a function (tree-shakeable) or a name string (lazy-imports the presets chunk). */
30
+ preset?: string | (() => Partial<StudioConfig$1>);
31
+ /** Escape hatch: a full/partial config, applied last. Precedence: default ← preset ← flat props ← config. */
32
+ config?: Partial<StudioConfig$1>;
33
+ poster?: string;
34
+ lazy?: boolean;
35
+ webgl?: "auto" | "force" | "off";
36
+ respectReducedMotion?: boolean;
37
+ className?: string;
38
+ style?: CSSProperties;
39
+ /** Custom SSR poster markup, e.g. `<img data-wave3d-poster src="…" />` — the shell adopts it. */
40
+ children?: ReactNode;
41
+ onReady?: (renderer: WaveRenderer$1) => void;
42
+ onFallback?: (reason: FallbackReason$1) => void;
43
+ }
44
+ /**
45
+ * A drop-in, self-optimizing gradient wave. Renders a `<div>` (SSR-safe; pass an
46
+ * `<img data-wave3d-poster>` child for a server-rendered poster) and, on the client, mounts the
47
+ * shell — poster-first, lazy, WebGL/reduced-motion/save-data aware, with the engine code-split out.
48
+ */
49
+ declare function Wave3D(props: Wave3DProps): ReactElement;
50
+ //#endregion
51
+ export { type FallbackReason, type StudioConfig, Wave3D, Wave3D as default, Wave3DProps, type WaveHandle, type WaveRenderer };
52
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,136 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { createDefaultConfig, createWave, makeStops } from "@wave3d/core";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/index.tsx
6
+ function normalizePalette(p) {
7
+ return p.length > 0 && typeof p[0] === "string" ? makeStops(p) : p;
8
+ }
9
+ /** Resolve the base config: function preset (sync) → its config; string preset → lazy-load presets. */
10
+ async function resolveBase(preset) {
11
+ if (typeof preset === "function") return {
12
+ ...createDefaultConfig(),
13
+ ...preset()
14
+ };
15
+ if (typeof preset === "string") {
16
+ const { PRESETS } = await import("@wave3d/core/presets");
17
+ const make = PRESETS[preset];
18
+ if (make) return make();
19
+ }
20
+ return createDefaultConfig();
21
+ }
22
+ /** Base config we can build synchronously (function preset / default) — a string preset resolves later. */
23
+ function syncBase(preset) {
24
+ return typeof preset === "function" ? {
25
+ ...createDefaultConfig(),
26
+ ...preset()
27
+ } : createDefaultConfig();
28
+ }
29
+ /** Apply the flat props (and the config escape hatch) onto a full base config. */
30
+ function buildConfig(base, props) {
31
+ const w = base.waves[0];
32
+ if (props.palette !== void 0) w.palette = normalizePalette(props.palette);
33
+ if (props.fiberCount !== void 0) w.fiberCount = props.fiberCount;
34
+ if (props.fiberStrength !== void 0) w.fiberStrength = props.fiberStrength;
35
+ if (props.sheen !== void 0) w.sheen = props.sheen;
36
+ if (props.iridescence !== void 0) w.iridescence = props.iridescence;
37
+ if (props.displaceAmount !== void 0) w.displaceAmount = props.displaceAmount;
38
+ if (props.speed !== void 0) w.speed = props.speed;
39
+ if (props.opacity !== void 0) w.opacity = props.opacity;
40
+ if (props.blendMode !== void 0) w.blendMode = props.blendMode;
41
+ if (props.theme !== void 0) w.theme = props.theme;
42
+ if (props.background !== void 0) base.background = props.background;
43
+ if (props.transparentBackground !== void 0) base.transparentBackground = props.transparentBackground;
44
+ if (props.quality !== void 0) base.quality = props.quality;
45
+ if (props.dprMax !== void 0) base.dprMax = props.dprMax;
46
+ if (props.loopSeconds !== void 0) base.loopSeconds = props.loopSeconds;
47
+ if (props.introRamp !== void 0) base.introRamp = props.introRamp;
48
+ if (props.paused !== void 0) base.paused = props.paused;
49
+ return {
50
+ ...base,
51
+ ...props.config
52
+ };
53
+ }
54
+ /** A stable string that changes whenever the resolved config would — keys the update effect. */
55
+ function configKey(props) {
56
+ const flat = {};
57
+ for (const k of [
58
+ "palette",
59
+ "fiberCount",
60
+ "fiberStrength",
61
+ "sheen",
62
+ "iridescence",
63
+ "displaceAmount",
64
+ "speed",
65
+ "opacity",
66
+ "blendMode",
67
+ "theme",
68
+ "background",
69
+ "transparentBackground",
70
+ "quality",
71
+ "dprMax",
72
+ "loopSeconds",
73
+ "introRamp",
74
+ "paused"
75
+ ]) if (props[k] !== void 0) flat[k] = props[k];
76
+ return JSON.stringify({
77
+ preset: typeof props.preset === "function" ? "fn" : props.preset,
78
+ flat,
79
+ config: props.config
80
+ });
81
+ }
82
+ /**
83
+ * A drop-in, self-optimizing gradient wave. Renders a `<div>` (SSR-safe; pass an
84
+ * `<img data-wave3d-poster>` child for a server-rendered poster) and, on the client, mounts the
85
+ * shell — poster-first, lazy, WebGL/reduced-motion/save-data aware, with the engine code-split out.
86
+ */
87
+ function Wave3D(props) {
88
+ const { className, style, children } = props;
89
+ const containerRef = useRef(null);
90
+ const handleRef = useRef(null);
91
+ const cbRef = useRef({});
92
+ cbRef.current.onReady = props.onReady;
93
+ cbRef.current.onFallback = props.onFallback;
94
+ useEffect(() => {
95
+ const container = containerRef.current;
96
+ if (!container) return;
97
+ let cancelled = false;
98
+ const options = {
99
+ poster: props.poster,
100
+ lazy: props.lazy,
101
+ webgl: props.webgl,
102
+ respectReducedMotion: props.respectReducedMotion,
103
+ onReady: (r) => cbRef.current.onReady?.(r),
104
+ onFallback: (reason) => cbRef.current.onFallback?.(reason)
105
+ };
106
+ const handle = createWave(container, buildConfig(syncBase(props.preset), props), options);
107
+ handleRef.current = handle;
108
+ if (typeof props.preset === "string") resolveBase(props.preset).then((base) => {
109
+ if (!cancelled && handleRef.current === handle) handle.set(buildConfig(base, props));
110
+ });
111
+ return () => {
112
+ cancelled = true;
113
+ handle.destroy();
114
+ handleRef.current = null;
115
+ };
116
+ }, []);
117
+ useEffect(() => {
118
+ const handle = handleRef.current;
119
+ if (!handle) return;
120
+ const apply = (base) => {
121
+ if (handleRef.current === handle) handle.set(buildConfig(base, props));
122
+ };
123
+ if (typeof props.preset === "string") resolveBase(props.preset).then(apply);
124
+ else apply(syncBase(props.preset));
125
+ }, [configKey(props)]);
126
+ return /* @__PURE__ */ jsx("div", {
127
+ ref: containerRef,
128
+ className,
129
+ style,
130
+ children
131
+ });
132
+ }
133
+ //#endregion
134
+ export { Wave3D, Wave3D as default };
135
+
136
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport type { CSSProperties, ReactNode, ReactElement } from \"react\";\nimport { createWave, createDefaultConfig, makeStops } from \"@wave3d/core\";\nimport type {\n StudioConfig,\n WaveConfig,\n ColorStop,\n BlendMode,\n WaveHandle,\n WaveOptions,\n WaveRenderer,\n FallbackReason,\n} from \"@wave3d/core\";\n\n/** Flat props mapped onto the first wave. */\ninterface FlatWaveProps {\n palette?: string[] | ColorStop[];\n fiberCount?: number;\n fiberStrength?: number;\n sheen?: number;\n iridescence?: number;\n displaceAmount?: number;\n speed?: number;\n opacity?: number;\n blendMode?: BlendMode;\n theme?: \"solid\" | \"wireframe\";\n}\n\n/** Flat props mapped onto the scene. */\ninterface FlatSceneProps {\n background?: string;\n transparentBackground?: boolean;\n quality?: number;\n dprMax?: number;\n loopSeconds?: number;\n introRamp?: boolean;\n paused?: boolean;\n}\n\nexport interface Wave3DProps extends FlatWaveProps, FlatSceneProps {\n /** A preset: a function (tree-shakeable) or a name string (lazy-imports the presets chunk). */\n preset?: string | (() => Partial<StudioConfig>);\n /** Escape hatch: a full/partial config, applied last. Precedence: default ← preset ← flat props ← config. */\n config?: Partial<StudioConfig>;\n poster?: string;\n lazy?: boolean;\n webgl?: \"auto\" | \"force\" | \"off\";\n respectReducedMotion?: boolean;\n className?: string;\n style?: CSSProperties;\n /** Custom SSR poster markup, e.g. `<img data-wave3d-poster src=\"…\" />` — the shell adopts it. */\n children?: ReactNode;\n onReady?: (renderer: WaveRenderer) => void;\n onFallback?: (reason: FallbackReason) => void;\n}\n\nfunction normalizePalette(p: string[] | ColorStop[]): ColorStop[] {\n return p.length > 0 && typeof p[0] === \"string\" ? makeStops(p as string[]) : (p as ColorStop[]);\n}\n\n/** Resolve the base config: function preset (sync) → its config; string preset → lazy-load presets. */\nasync function resolveBase(preset: Wave3DProps[\"preset\"]): Promise<StudioConfig> {\n if (typeof preset === \"function\") return { ...createDefaultConfig(), ...preset() };\n if (typeof preset === \"string\") {\n const { PRESETS } = await import(\"@wave3d/core/presets\");\n const make = PRESETS[preset];\n if (make) return make();\n }\n return createDefaultConfig();\n}\n\n/** Base config we can build synchronously (function preset / default) — a string preset resolves later. */\nfunction syncBase(preset: Wave3DProps[\"preset\"]): StudioConfig {\n return typeof preset === \"function\"\n ? { ...createDefaultConfig(), ...preset() }\n : createDefaultConfig();\n}\n\n/** Apply the flat props (and the config escape hatch) onto a full base config. */\nfunction buildConfig(base: StudioConfig, props: Wave3DProps): Partial<StudioConfig> {\n const w: WaveConfig = base.waves[0];\n if (props.palette !== undefined) w.palette = normalizePalette(props.palette);\n if (props.fiberCount !== undefined) w.fiberCount = props.fiberCount;\n if (props.fiberStrength !== undefined) w.fiberStrength = props.fiberStrength;\n if (props.sheen !== undefined) w.sheen = props.sheen;\n if (props.iridescence !== undefined) w.iridescence = props.iridescence;\n if (props.displaceAmount !== undefined) w.displaceAmount = props.displaceAmount;\n if (props.speed !== undefined) w.speed = props.speed;\n if (props.opacity !== undefined) w.opacity = props.opacity;\n if (props.blendMode !== undefined) w.blendMode = props.blendMode;\n if (props.theme !== undefined) w.theme = props.theme;\n if (props.background !== undefined) base.background = props.background;\n if (props.transparentBackground !== undefined)\n base.transparentBackground = props.transparentBackground;\n if (props.quality !== undefined) base.quality = props.quality;\n if (props.dprMax !== undefined) base.dprMax = props.dprMax;\n if (props.loopSeconds !== undefined) base.loopSeconds = props.loopSeconds;\n if (props.introRamp !== undefined) base.introRamp = props.introRamp;\n if (props.paused !== undefined) base.paused = props.paused;\n return { ...base, ...props.config };\n}\n\n/** A stable string that changes whenever the resolved config would — keys the update effect. */\nfunction configKey(props: Wave3DProps): string {\n const flat: Record<string, unknown> = {};\n const keys = [\n \"palette\",\n \"fiberCount\",\n \"fiberStrength\",\n \"sheen\",\n \"iridescence\",\n \"displaceAmount\",\n \"speed\",\n \"opacity\",\n \"blendMode\",\n \"theme\",\n \"background\",\n \"transparentBackground\",\n \"quality\",\n \"dprMax\",\n \"loopSeconds\",\n \"introRamp\",\n \"paused\",\n ] as const;\n for (const k of keys) if (props[k] !== undefined) flat[k] = props[k];\n return JSON.stringify({\n preset: typeof props.preset === \"function\" ? \"fn\" : props.preset,\n flat,\n config: props.config,\n });\n}\n\n/**\n * A drop-in, self-optimizing gradient wave. Renders a `<div>` (SSR-safe; pass an\n * `<img data-wave3d-poster>` child for a server-rendered poster) and, on the client, mounts the\n * shell — poster-first, lazy, WebGL/reduced-motion/save-data aware, with the engine code-split out.\n */\nexport function Wave3D(props: Wave3DProps): ReactElement {\n const { className, style, children } = props;\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<WaveHandle | null>(null);\n // Keep the latest callbacks in a ref so they never force a remount.\n const cbRef = useRef<Pick<Wave3DProps, \"onReady\" | \"onFallback\">>({});\n cbRef.current.onReady = props.onReady;\n cbRef.current.onFallback = props.onFallback;\n\n // Mount once. StrictMode double-mount is safe: destroy() aborts a pending upgrade, and the\n // pre-upgrade create/destroy is DOM-only (poster + IntersectionObserver).\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n let cancelled = false;\n const options: WaveOptions = {\n poster: props.poster,\n lazy: props.lazy,\n webgl: props.webgl,\n respectReducedMotion: props.respectReducedMotion,\n onReady: (r) => cbRef.current.onReady?.(r),\n onFallback: (reason) => cbRef.current.onFallback?.(reason),\n };\n const handle = createWave(container, buildConfig(syncBase(props.preset), props), options);\n handleRef.current = handle;\n // A string preset resolves asynchronously; stage/set the real config once it loads.\n if (typeof props.preset === \"string\") {\n void resolveBase(props.preset).then((base) => {\n if (!cancelled && handleRef.current === handle) handle.set(buildConfig(base, props));\n });\n }\n return () => {\n cancelled = true;\n handle.destroy();\n handleRef.current = null;\n };\n // Mount-time only (options are captured once; config changes flow through the effect below).\n }, []);\n\n // Push config changes (flat props / config / preset) to the live handle.\n const key = configKey(props);\n useEffect(() => {\n const handle = handleRef.current;\n if (!handle) return;\n const apply = (base: StudioConfig): void => {\n if (handleRef.current === handle) handle.set(buildConfig(base, props));\n };\n if (typeof props.preset === \"string\") void resolveBase(props.preset).then(apply);\n else apply(syncBase(props.preset));\n // Re-runs only when the serialized config (`key`) changes; `props` is read fresh inside.\n }, [key]);\n\n return (\n <div ref={containerRef} className={className} style={style}>\n {children}\n </div>\n );\n}\n\nexport default Wave3D;\nexport type { StudioConfig, WaveHandle, WaveRenderer, FallbackReason } from \"@wave3d/core\";\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@wave3d/react",
3
+ "version": "0.1.0",
4
+ "description": "React <Wave3D> component for @wave3d — a drop-in, self-optimizing animated gradient wave",
5
+ "keywords": [
6
+ "animation",
7
+ "background",
8
+ "component",
9
+ "gradient",
10
+ "react",
11
+ "three",
12
+ "threejs",
13
+ "wave",
14
+ "webgl"
15
+ ],
16
+ "homepage": "https://github.com/Amir-Abushanab/wave3d/tree/main/packages/react#readme",
17
+ "bugs": "https://github.com/Amir-Abushanab/wave3d/issues",
18
+ "license": "MIT",
19
+ "author": "Amir Abushanab (https://github.com/Amir-Abushanab)",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Amir-Abushanab/wave3d.git",
23
+ "directory": "packages/react"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "devDependencies": {
40
+ "@types/react": "^19.0.0",
41
+ "react": "^19.0.0",
42
+ "@wave3d/core": "0.1.0"
43
+ },
44
+ "peerDependencies": {
45
+ "react": ">=18",
46
+ "@wave3d/core": "^0.1.0"
47
+ },
48
+ "scripts": {
49
+ "typecheck": "tsc --noEmit",
50
+ "build": "tsdown"
51
+ }
52
+ }