@wave3d/react 0.7.0 → 0.9.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, ReactElement, ReactNode } from "react";
2
- import { BlendMode, ColorStop, FallbackReason, FallbackReason as FallbackReason$1, PosterFit, SnapshotOptions, StudioConfig, StudioConfig as StudioConfig$1, WaveHandle, WaveInteractionConfig, WaveRenderer, WaveRenderer as WaveRenderer$1 } from "@wave3d/core";
2
+ import { BlendMode, ColorStop, FallbackReason, FallbackReason as FallbackReason$1, PosterFit, SnapshotOptions, StudioConfig, StudioConfig as StudioConfig$1, WaveHandle, WaveInteractionConfig, WaveOptions, WaveRenderer, WaveRenderer as WaveRenderer$1 } from "@wave3d/core";
3
3
  //#region src/index.d.ts
4
4
  /** Flat props mapped onto the first wave. */
5
5
  interface FlatWaveProps {
@@ -37,6 +37,11 @@ interface Wave3DProps extends FlatWaveProps, FlatSceneProps {
37
37
  posterFit?: PosterFit;
38
38
  lazy?: boolean;
39
39
  webgl?: "auto" | "force" | "off";
40
+ /**
41
+ * Renderer backend. Default `"webgl"`. `"webgpu"` / `"auto"` fetch a separate ~197 KB (gzipped)
42
+ * chunk holding three's node system, so they are opt-in.
43
+ */
44
+ backend?: WaveOptions["backend"];
40
45
  respectReducedMotion?: boolean;
41
46
  className?: string;
42
47
  style?: CSSProperties;
package/dist/index.js CHANGED
@@ -102,6 +102,7 @@ function Wave3D(props) {
102
102
  posterFit: props.posterFit,
103
103
  lazy: props.lazy,
104
104
  webgl: props.webgl,
105
+ backend: props.backend,
105
106
  respectReducedMotion: props.respectReducedMotion,
106
107
  onReady: (r) => cbRef.current.onReady?.(r),
107
108
  onFallback: (reason) => cbRef.current.onFallback?.(reason)
package/dist/index.js.map CHANGED
@@ -1 +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 WaveInteractionConfig,\n WaveHandle,\n WaveOptions,\n WaveRenderer,\n FallbackReason,\n PosterFit,\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 /** Per-wave interactivity for the first wave (hover field / click / bindings). Off when omitted.\n * Scene-level shared inputs + scene bindings go through the `config` prop. */\n interaction?: WaveInteractionConfig;\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 /** Poster `object-fit`. Default `\"fill\"` (matches the canvas → seamless handoff); `\"cover\"` crops. */\n posterFit?: PosterFit;\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.interaction !== undefined) w.interaction = props.interaction;\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 \"interaction\",\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 posterFit: props.posterFit,\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 {\n StudioConfig,\n WaveHandle,\n WaveRenderer,\n FallbackReason,\n SnapshotOptions,\n} from \"@wave3d/core\";\n"],"mappings":"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"}
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 WaveInteractionConfig,\n WaveHandle,\n WaveOptions,\n WaveRenderer,\n FallbackReason,\n PosterFit,\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 /** Per-wave interactivity for the first wave (hover field / click / bindings). Off when omitted.\n * Scene-level shared inputs + scene bindings go through the `config` prop. */\n interaction?: WaveInteractionConfig;\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 /** Poster `object-fit`. Default `\"fill\"` (matches the canvas → seamless handoff); `\"cover\"` crops. */\n posterFit?: PosterFit;\n lazy?: boolean;\n webgl?: \"auto\" | \"force\" | \"off\";\n /**\n * Renderer backend. Default `\"webgl\"`. `\"webgpu\"` / `\"auto\"` fetch a separate ~197 KB (gzipped)\n * chunk holding three's node system, so they are opt-in.\n */\n backend?: WaveOptions[\"backend\"];\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.interaction !== undefined) w.interaction = props.interaction;\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 \"interaction\",\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 posterFit: props.posterFit,\n lazy: props.lazy,\n webgl: props.webgl,\n backend: props.backend,\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 {\n StudioConfig,\n WaveHandle,\n WaveRenderer,\n FallbackReason,\n SnapshotOptions,\n} from \"@wave3d/core\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wave3d/react",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Drop-in animated 3D gradient wave for React: the <Wave3D> component",
5
5
  "keywords": [
6
6
  "animation",
@@ -37,7 +37,7 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@wave3d/core": "^0.7.0"
40
+ "@wave3d/core": "^0.9.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react": "^19.0.0",