@react-three/fiber 8.0.0-beta.4 → 8.0.0-beta.5

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.
@@ -1,5 +1,5 @@
1
1
  import * as THREE from 'three';
2
- import type { UseStore } from 'zustand';
2
+ import type { UseBoundStore } from 'zustand';
3
3
  import type { RootState } from './store';
4
4
  export interface Intersection extends THREE.Intersection {
5
5
  eventObject: THREE.Object3D;
@@ -58,7 +58,7 @@ export interface PointerCaptureTarget {
58
58
  target: Element;
59
59
  }
60
60
  export declare function getEventPriority(): any;
61
- export declare function removeInteractivity(store: UseStore<RootState>, object: THREE.Object3D): void;
62
- export declare function createEvents(store: UseStore<RootState>): {
61
+ export declare function removeInteractivity(store: UseBoundStore<RootState>, object: THREE.Object3D): void;
62
+ export declare function createEvents(store: UseBoundStore<RootState>): {
63
63
  handlePointer: (name: string) => (event: DomEvent) => void;
64
64
  };
@@ -1,5 +1,6 @@
1
1
  import * as THREE from 'three';
2
- import { StateSelector, EqualityChecker } from 'zustand';
2
+ import * as React from 'react';
3
+ import { StateSelector, EqualityChecker, UseBoundStore } from 'zustand';
3
4
  import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
4
5
  import { RootState, RenderCallback } from './store';
5
6
  import { ObjectMap } from './utils';
@@ -10,8 +11,11 @@ export declare type Extensions = (loader: THREE.Loader) => void;
10
11
  export declare type LoaderResult<T> = T extends any[] ? Loader<T[number]> : Loader<T>;
11
12
  export declare type ConditionalType<Child, Parent, Truthy, Falsy> = Child extends Parent ? Truthy : Falsy;
12
13
  export declare type BranchingReturn<T, Parent, Coerced> = ConditionalType<T, Parent, Coerced, T>;
13
- export declare function useStore(): import("zustand").UseStore<RootState, import("zustand").StoreApi<RootState>>;
14
+ export declare function useStore(): UseBoundStore<RootState, import("zustand").StoreApi<RootState>>;
14
15
  export declare function useThree<T = RootState>(selector?: StateSelector<RootState, T>, equalityFn?: EqualityChecker<T>): T;
16
+ export declare function useInject(state: Partial<RootState>): [React.FC<{
17
+ children: React.ReactNode;
18
+ }>, UseBoundStore<RootState, import("zustand").StoreApi<RootState>>];
15
19
  export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
16
20
  export declare function useGraph(object: THREE.Object3D): ObjectMap;
17
21
  export declare function useLoader<T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent<EventTarget>) => void): U extends any[] ? BranchingReturn<T, GLTF, GLTF & ObjectMap>[] : BranchingReturn<T, GLTF, GLTF & ObjectMap>;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react-reconciler" />
2
2
  import * as THREE from 'three';
3
3
  import * as React from 'react';
4
- import { UseStore } from 'zustand';
4
+ import { UseBoundStore } from 'zustand';
5
5
  import { Renderer, StoreProps, context, RootState, Size } from './store';
6
6
  import { extend, Root } from './renderer';
7
7
  import { addEffect, addAfterEffect, addTail } from './loop';
@@ -16,19 +16,19 @@ declare type Properties<T> = Pick<T, {
16
16
  declare type GLProps = Renderer | ((canvas: HTMLCanvasElement) => Renderer) | Partial<Properties<THREE.WebGLRenderer> | THREE.WebGLRendererParameters> | undefined;
17
17
  export declare type RenderProps<TCanvas extends Element> = Omit<StoreProps, 'gl' | 'events' | 'size'> & {
18
18
  gl?: GLProps;
19
- events?: (store: UseStore<RootState>) => EventManager<TCanvas>;
19
+ events?: (store: UseBoundStore<RootState>) => EventManager<TCanvas>;
20
20
  size?: Size;
21
21
  onCreated?: (state: RootState) => void;
22
22
  };
23
23
  export declare type ReconcilerRoot<TCanvas extends Element> = {
24
24
  configure: (config?: RenderProps<TCanvas>) => ReconcilerRoot<TCanvas>;
25
- render: (element: React.ReactNode) => UseStore<RootState>;
25
+ render: (element: React.ReactNode) => UseBoundStore<RootState>;
26
26
  unmount: () => void;
27
27
  };
28
28
  declare function createRoot<TCanvas extends Element>(canvas: TCanvas): ReconcilerRoot<TCanvas>;
29
- declare function render<TCanvas extends Element>(element: React.ReactNode, canvas: TCanvas, config?: RenderProps<TCanvas>): UseStore<RootState>;
29
+ declare function render<TCanvas extends Element>(element: React.ReactNode, canvas: TCanvas, config?: RenderProps<TCanvas>): UseBoundStore<RootState>;
30
30
  declare function unmountComponentAtNode<TElement extends Element>(canvas: TElement, callback?: (canvas: TElement) => void): void;
31
+ declare function createPortal(children: React.ReactNode, container: THREE.Object3D, state?: Partial<RootState>): React.ReactNode;
31
32
  declare const act: any;
32
- declare function createPortal(children: React.ReactNode, container: THREE.Object3D): React.ReactNode;
33
33
  export * from './hooks';
34
34
  export { context, render, createRoot, unmountComponentAtNode, createPortal, reconciler, applyProps, dispose, invalidate, advance, extend, addEffect, addAfterEffect, addTail, act, roots as _roots, };
@@ -1,38 +1,29 @@
1
1
  import * as THREE from 'three';
2
- import { UseStore } from 'zustand';
2
+ import { UseBoundStore } from 'zustand';
3
3
  import Reconciler from 'react-reconciler';
4
4
  import { prepare, applyProps } from './utils';
5
5
  import { RootState } from './store';
6
6
  import { EventHandlers } from './events';
7
7
  export declare type Root = {
8
8
  fiber: Reconciler.FiberRoot;
9
- store: UseStore<RootState>;
9
+ store: UseBoundStore<RootState>;
10
10
  };
11
- export declare type HostContext = React.MutableRefObject<{
12
- [key: string]: any;
13
- } | null>;
14
11
  export declare type LocalState = {
15
12
  type: string;
16
- root: UseStore<RootState>;
17
- context: React.MutableRefObject<{
18
- [key: string]: any;
19
- } | null>;
20
- getContext: () => {
21
- [key: string]: any;
22
- };
13
+ root: UseBoundStore<RootState>;
23
14
  objects: Instance[];
24
15
  parent: Instance | null;
25
16
  primitive?: boolean;
26
17
  eventCount: number;
27
18
  handlers: Partial<EventHandlers>;
28
19
  attach?: AttachType;
29
- previousAttach?: any;
20
+ previousAttach: any;
30
21
  memoizedProps: {
31
22
  [key: string]: any;
32
23
  };
33
24
  };
34
- export declare type AttachFnType = (parent: Instance, self: Instance) => void;
35
- export declare type AttachType = string | [attach: string | AttachFnType, detach: string | AttachFnType];
25
+ export declare type AttachFnType = (parent: Instance, self: Instance) => () => void;
26
+ export declare type AttachType = string | AttachFnType;
36
27
  export declare type BaseInstance = Omit<THREE.Object3D, 'children' | 'attach' | 'add' | 'remove' | 'raycast'> & {
37
28
  __r3f: LocalState;
38
29
  children: Instance[];
@@ -1,7 +1,7 @@
1
1
  import * as THREE from 'three';
2
2
  import * as React from 'react';
3
3
  import * as ReactThreeFiber from '../three-types';
4
- import { GetState, SetState, UseStore } from 'zustand';
4
+ import { GetState, SetState, UseBoundStore } from 'zustand';
5
5
  import { DomEvent, EventManager, PointerCaptureTarget, ThreeEvent } from './events';
6
6
  export interface Intersection extends THREE.Intersection {
7
7
  eventObject: THREE.Object3D;
@@ -110,6 +110,6 @@ export declare type StoreProps = {
110
110
  };
111
111
  onPointerMissed?: (event: MouseEvent) => void;
112
112
  };
113
- declare const context: React.Context<UseStore<RootState, import("zustand").StoreApi<RootState>>>;
114
- declare const createStore: (invalidate: (state?: RootState | undefined) => void, advance: (timestamp: number, runGlobalEffects?: boolean | undefined, state?: RootState | undefined, frame?: THREE.XRFrame | undefined) => void) => UseStore<RootState>;
113
+ declare const context: React.Context<UseBoundStore<RootState, import("zustand").StoreApi<RootState>>>;
114
+ declare const createStore: (invalidate: (state?: RootState | undefined) => void, advance: (timestamp: number, runGlobalEffects?: boolean | undefined, state?: RootState | undefined, frame?: THREE.XRFrame | undefined) => void) => UseBoundStore<RootState>;
115
115
  export { createStore, context };
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { View, ViewProps, ViewStyle } from 'react-native';
3
- import { UseStore } from 'zustand';
3
+ import { UseBoundStore } from 'zustand';
4
4
  import { RenderProps } from '../core';
5
5
  import { RootState } from '../core/store';
6
6
  import { EventManager } from '../core/events';
@@ -8,6 +8,6 @@ export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size' | 'ev
8
8
  children: React.ReactNode;
9
9
  fallback?: React.ReactNode;
10
10
  style?: ViewStyle;
11
- events?: (store: UseStore<RootState>) => EventManager<any>;
11
+ events?: (store: UseBoundStore<RootState>) => EventManager<any>;
12
12
  }
13
13
  export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<View>>;
@@ -1,5 +1,5 @@
1
- import { UseStore } from 'zustand';
1
+ import { UseBoundStore } from 'zustand';
2
2
  import { RootState } from '../core/store';
3
3
  import { EventManager } from '../core/events';
4
4
  import { View } from 'react-native';
5
- export declare function createTouchEvents(store: UseStore<RootState>): EventManager<View>;
5
+ export declare function createTouchEvents(store: UseBoundStore<RootState>): EventManager<View>;
@@ -320,11 +320,6 @@ declare global {
320
320
  fog: FogProps;
321
321
  fogExp2: FogExp2Props;
322
322
  shape: ShapeProps;
323
- inject: {
324
- children: React.ReactNode;
325
- } & {
326
- [key: string]: any;
327
- };
328
323
  }
329
324
  }
330
325
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { Options as ResizeOptions } from 'react-use-measure';
3
- import { UseStore } from 'zustand';
3
+ import { UseBoundStore } from 'zustand';
4
4
  import { RenderProps } from '../core';
5
5
  import { RootState } from '../core/store';
6
6
  import { EventManager } from '../core/events';
@@ -8,6 +8,6 @@ export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size' | 'ev
8
8
  children: React.ReactNode;
9
9
  fallback?: React.ReactNode;
10
10
  resize?: ResizeOptions;
11
- events?: (store: UseStore<RootState>) => EventManager<any>;
11
+ events?: (store: UseBoundStore<RootState>) => EventManager<any>;
12
12
  }
13
13
  export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLCanvasElement>>;
@@ -1,4 +1,4 @@
1
- import { UseStore } from 'zustand';
1
+ import { UseBoundStore } from 'zustand';
2
2
  import { RootState } from '../core/store';
3
3
  import { EventManager } from '../core/events';
4
- export declare function createPointerEvents(store: UseStore<RootState>): EventManager<HTMLElement>;
4
+ export declare function createPointerEvents(store: UseBoundStore<RootState>): EventManager<HTMLElement>;
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
2
- import { suspend, preload, clear } from 'suspend-react';
3
1
  import * as THREE from 'three';
2
+ import * as React from 'react';
4
3
  import { DefaultEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
5
4
  import create from 'zustand';
6
5
  import Reconciler from 'react-reconciler';
7
6
  import { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
7
+ import { suspend, preload, clear } from 'suspend-react';
8
8
 
9
9
  var threeTypes = /*#__PURE__*/Object.freeze({
10
10
  __proto__: null
@@ -66,7 +66,7 @@ const is = {
66
66
  const isArr = is.arr(a);
67
67
  if (isArr && arrays === 'reference') return a === b; // Array or Object, shallow compare first to see if it's a match
68
68
 
69
- if ((isArr || isObj) && a == b) return true; // Last resort, go through keys
69
+ if ((isArr || isObj) && a === b) return true; // Last resort, go through keys
70
70
 
71
71
  let i;
72
72
 
@@ -74,7 +74,13 @@ const is = {
74
74
 
75
75
  for (i in strict ? b : a) if (a[i] !== b[i]) return false;
76
76
 
77
- return is.und(i) ? a === b : true;
77
+ if (is.und(i)) {
78
+ if (isArr && a.length === 0 && b.length === 0) return true;
79
+ if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
80
+ if (a !== b) return false;
81
+ }
82
+
83
+ return true;
78
84
  }
79
85
 
80
86
  }; // Collects nodes and materials from a THREE.Object3D
@@ -110,30 +116,8 @@ function prepare(object, state) {
110
116
  if (state != null && state.primitive || !instance.__r3f) {
111
117
  instance.__r3f = {
112
118
  type: '',
113
- context: {
114
- current: null
115
- },
116
- getContext: () => {
117
- const injects = [];
118
- let inject = instance.__r3f.context.current;
119
-
120
- while (inject) {
121
- var _inject$memoizedProps, _inject, _inject$context;
122
-
123
- const {
124
- children,
125
- args,
126
- ...props
127
- } = (_inject$memoizedProps = (_inject = inject) == null ? void 0 : _inject.memoizedProps) != null ? _inject$memoizedProps : {};
128
- injects.push(props);
129
- inject = (_inject$context = inject.context) == null ? void 0 : _inject$context.current;
130
- }
131
-
132
- return injects.reverse().reduce((prev, cur) => ({ ...prev,
133
- ...cur
134
- }), {});
135
- },
136
119
  root: null,
120
+ previousAttach: null,
137
121
  memoizedProps: {},
138
122
  eventCount: 0,
139
123
  handlers: {},
@@ -161,32 +145,42 @@ function resolve(instance, key) {
161
145
  target,
162
146
  key
163
147
  };
164
- }
148
+ } // Checks if a dash-cased string ends with an integer
165
149
 
150
+
151
+ const INDEX_REGEX = /-\d+$/;
166
152
  function attach(parent, child, type) {
167
153
  if (is.str(type)) {
154
+ // If attaching into an array (foo-0), create one
155
+ if (INDEX_REGEX.test(type)) {
156
+ const root = type.replace(INDEX_REGEX, '');
157
+ const {
158
+ target,
159
+ key
160
+ } = resolve(parent, root);
161
+ if (!Array.isArray(target[key])) target[key] = [];
162
+ }
163
+
168
164
  const {
169
165
  target,
170
166
  key
171
167
  } = resolve(parent, type);
172
- parent.__r3f.previousAttach = target[key];
168
+ child.__r3f.previousAttach = target[key];
173
169
  target[key] = child;
174
- } else if (is.arr(type)) {
175
- const [attach] = type;
176
- if (is.str(attach)) parent[attach](child);else if (is.fun(attach)) attach(parent, child);
177
- }
170
+ } else child.__r3f.previousAttach = type(parent, child);
178
171
  }
179
172
  function detach(parent, child, type) {
173
+ var _child$__r3f, _child$__r3f2;
174
+
180
175
  if (is.str(type)) {
181
176
  const {
182
177
  target,
183
178
  key
184
179
  } = resolve(parent, type);
185
- target[key] = parent.__r3f.previousAttach;
186
- } else if (is.arr(type)) {
187
- const [, detach] = type;
188
- if (is.str(detach)) parent[detach](child);else if (is.fun(detach)) detach(parent, child);
189
- }
180
+ target[key] = child.__r3f.previousAttach;
181
+ } else (_child$__r3f = child.__r3f) == null ? void 0 : _child$__r3f.previousAttach == null ? void 0 : _child$__r3f.previousAttach(parent, child);
182
+
183
+ (_child$__r3f2 = child.__r3f) == null ? true : delete _child$__r3f2.previousAttach;
190
184
  } // This function prepares a set of changes to be applied to the instance
191
185
 
192
186
  function diffProps(instance, {
@@ -306,20 +300,10 @@ function applyProps$1(instance, data) {
306
300
 
307
301
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
308
302
  else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
309
- else targetProp.set(value); // Auto-convert sRGB colors, for now ...
310
- // https://github.com/pmndrs/react-three-fiber/issues/344
311
-
312
- if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
303
+ else targetProp.set(value);
313
304
  } // Else, just overwrite the value
314
305
 
315
- } else {
316
- currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
317
- // https://github.com/pmndrs/react-three-fiber/issues/344
318
-
319
- if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) {
320
- currentInstance[key].encoding = THREE.sRGBEncoding;
321
- }
322
- }
306
+ } else currentInstance[key] = value;
323
307
 
324
308
  invalidateInstance(instance);
325
309
  return instance;
@@ -770,54 +754,20 @@ function createEvents(store) {
770
754
  };
771
755
  }
772
756
 
773
- // Type guard to tell a store from a portal
774
- const isStore = def => def && !!def.getState;
775
-
776
- const getContainer = (container, child) => {
777
- var _container$__r3f$root, _container$__r3f;
778
-
779
- return {
780
- // If the container is not a root-store then it must be a THREE.Object3D into which part of the
781
- // scene is portalled into. Now there can be two variants of this, either that object is part of
782
- // the regular jsx tree, in which case it already has __r3f with a valid root attached, or it lies
783
- // outside react, in which case we must take the root of the child that is about to be attached to it.
784
- root: isStore(container) ? container : (_container$__r3f$root = (_container$__r3f = container.__r3f) == null ? void 0 : _container$__r3f.root) != null ? _container$__r3f$root : child.__r3f.root,
785
- // The container is the eventual target into which objects are mounted, it has to be a THREE.Object3D
786
- container: isStore(container) ? container.getState().scene : container
787
- };
788
- };
789
-
790
757
  let catalogue = {};
791
758
 
792
759
  let extend = objects => void (catalogue = { ...catalogue,
793
760
  ...objects
794
761
  });
795
762
 
796
- extend({
797
- Inject: THREE.Group
798
- });
799
-
800
763
  function createRenderer(roots, getEventPriority) {
801
764
  function createInstance(type, {
802
765
  args = [],
803
766
  attach,
804
767
  ...props
805
- }, root, context, internalInstanceHandle) {
768
+ }, root) {
806
769
  let name = `${type[0].toUpperCase()}${type.slice(1)}`;
807
- let instance; // https://github.com/facebook/react/issues/17147
808
- // Portals do not give us a root, they are themselves treated as a root by the reconciler
809
- // In order to figure out the actual root we have to climb through fiber internals :(
810
-
811
- if (!isStore(root) && internalInstanceHandle) {
812
- const fn = node => {
813
- if (!node.return) return node.stateNode && node.stateNode.containerInfo;else return fn(node.return);
814
- };
815
-
816
- root = fn(internalInstanceHandle);
817
- } // Assert that by now we have a valid root
818
-
819
-
820
- if (!root || !isStore(root)) throw `No valid root for ${name}!`; // Auto-attach geometries and materials
770
+ let instance; // Auto-attach geometries and materials
821
771
 
822
772
  if (attach === undefined) {
823
773
  if (name.endsWith('Geometry')) attach = 'geometry';else if (name.endsWith('Material')) attach = 'material';
@@ -829,7 +779,6 @@ function createRenderer(roots, getEventPriority) {
829
779
  instance = prepare(object, {
830
780
  type,
831
781
  root,
832
- context,
833
782
  attach,
834
783
  primitive: true
835
784
  });
@@ -847,7 +796,6 @@ function createRenderer(roots, getEventPriority) {
847
796
  instance = prepare(new target(...args), {
848
797
  type,
849
798
  root,
850
- context,
851
799
  attach,
852
800
  // TODO: Figure out what this is for
853
801
  memoizedProps: {
@@ -865,15 +813,6 @@ function createRenderer(roots, getEventPriority) {
865
813
  }
866
814
 
867
815
  function appendChild(parentInstance, child) {
868
- // https://github.com/facebook/react/issues/24138
869
- // Injects are special purpose "onion layers" that inject contextual information into the scene graph.
870
- // Since react-reconciler does not allow us to access the current host context we trick it by leading
871
- // back to it from the first child that is added to it. We just connect the inject to it's own host context.
872
- if ((parentInstance == null ? void 0 : parentInstance.__r3f.type) === 'inject') {
873
- const context = child == null ? void 0 : child.__r3f.context;
874
- if (context) context.current = parentInstance.__r3f;
875
- }
876
-
877
816
  let added = false;
878
817
 
879
818
  if (child) {
@@ -969,7 +908,6 @@ function createRenderer(roots, getEventPriority) {
969
908
 
970
909
  if (child.__r3f) {
971
910
  delete child.__r3f.root;
972
- delete child.__r3f.context;
973
911
  delete child.__r3f.objects;
974
912
  delete child.__r3f.handlers;
975
913
  delete child.__r3f.memoizedProps;
@@ -992,11 +930,11 @@ function createRenderer(roots, getEventPriority) {
992
930
  }
993
931
 
994
932
  function switchInstance(instance, type, newProps, fiber) {
995
- var _instance$__r3f;
933
+ var _instance$__r3f, _instance$__r3f2;
996
934
 
997
935
  const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
998
936
  if (!parent) return;
999
- const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
937
+ const newInstance = createInstance(type, newProps, (_instance$__r3f2 = instance.__r3f) == null ? void 0 : _instance$__r3f2.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
1000
938
  // When args change the instance has to be re-constructed, which then
1001
939
  // forces r3f to re-parent the children and non-scene objects
1002
940
  // This can not include primitives, which should not have declarative children
@@ -1039,46 +977,28 @@ function createRenderer(roots, getEventPriority) {
1039
977
  supportsMutation: true,
1040
978
  isPrimaryRenderer: false,
1041
979
  noTimeout: -1,
1042
- appendChildToContainer: (parentInstance, child) => {
1043
- const {
1044
- container,
1045
- root
1046
- } = getContainer(parentInstance, child); // Link current root to the default scene
980
+ appendChildToContainer: (container, child) => {
981
+ const scene = container.getState().scene; // Link current root to the default scene
1047
982
 
1048
- container.__r3f.root = root;
1049
- appendChild(container, child);
1050
- },
1051
- removeChildFromContainer: (parentInstance, child) => removeChild(getContainer(parentInstance, child).container, child),
1052
- insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
1053
- getRootHostContext: () => ({
1054
- current: null
1055
- }),
1056
- getChildHostContext: (parentHostContext, type) => {
1057
- // This is a little misleading, this function does not determine the host context for the element at hand,
1058
- // but rather for all the children of it. The context for an inject is and will be the scene, everything
1059
- // within an inject is contextual to it.
1060
- if (type === 'inject') return {
1061
- current: null
1062
- };
1063
- return parentHostContext;
983
+ scene.__r3f.root = container;
984
+ appendChild(scene, child);
1064
985
  },
986
+ removeChildFromContainer: (container, child) => removeChild(container.getState().scene, child),
987
+ insertInContainerBefore: (container, child, beforeChild) => insertBefore(container.getState().scene, child, beforeChild),
988
+ getRootHostContext: () => null,
989
+ getChildHostContext: parentHostContext => parentHostContext,
1065
990
 
1066
991
  finalizeInitialChildren(instance) {
1067
- var _instance$__r3f2;
992
+ var _instance$__r3f3;
1068
993
 
1069
- const localState = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {}; // https://github.com/facebook/react/issues/20271
994
+ const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {}; // https://github.com/facebook/react/issues/20271
1070
995
  // Returning true will trigger commitMount
1071
996
 
1072
997
  return !!localState.handlers;
1073
998
  },
1074
999
 
1075
1000
  prepareUpdate(instance, type, oldProps, newProps) {
1076
- // Injects are special purpose "onion layers" that inject contextual information into the scene graph
1077
- // Because the context of an inject is still the scene we have to rely on children to give us the inject-context
1078
- // so that we can set up props.
1079
- if (type === 'inject' && instance.children.length) ; // Create diff-sets
1080
-
1081
-
1001
+ // Create diff-sets
1082
1002
  if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) {
1083
1003
  return [true];
1084
1004
  } else {
@@ -1112,11 +1032,11 @@ function createRenderer(roots, getEventPriority) {
1112
1032
  },
1113
1033
 
1114
1034
  commitMount(instance, type, props, int) {
1115
- var _instance$__r3f3;
1035
+ var _instance$__r3f4;
1116
1036
 
1117
1037
  // https://github.com/facebook/react/issues/20271
1118
1038
  // This will make sure events are only added once to the central container
1119
- const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {};
1039
+ const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1120
1040
 
1121
1041
  if (instance.raycast && localState.handlers && localState.eventCount) {
1122
1042
  instance.__r3f.root.getState().internal.interaction.push(instance);
@@ -1126,7 +1046,7 @@ function createRenderer(roots, getEventPriority) {
1126
1046
  getPublicInstance: instance => instance,
1127
1047
  shouldDeprioritizeSubtree: () => false,
1128
1048
  prepareForCommit: () => null,
1129
- preparePortalMount: containerInfo => prepare(containerInfo),
1049
+ preparePortalMount: container => prepare(container.getState().scene),
1130
1050
  resetAfterCommit: () => {},
1131
1051
  shouldSetTextContent: () => false,
1132
1052
  clearContainer: () => false,
@@ -1134,26 +1054,26 @@ function createRenderer(roots, getEventPriority) {
1134
1054
  createTextInstance: () => {},
1135
1055
 
1136
1056
  hideInstance(instance) {
1137
- var _instance$__r3f4;
1057
+ var _instance$__r3f5;
1138
1058
 
1139
1059
  // Deatch while the instance is hidden
1140
1060
  const {
1141
1061
  attach: type,
1142
1062
  parent
1143
- } = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1063
+ } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1144
1064
  if (type && parent) detach(parent, instance, type);
1145
1065
  if (instance.isObject3D) instance.visible = false;
1146
1066
  invalidateInstance(instance);
1147
1067
  },
1148
1068
 
1149
1069
  unhideInstance(instance, props) {
1150
- var _instance$__r3f5;
1070
+ var _instance$__r3f6;
1151
1071
 
1152
1072
  // Re-attach when the instance is unhidden
1153
1073
  const {
1154
1074
  attach: type,
1155
1075
  parent
1156
- } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1076
+ } = (_instance$__r3f6 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f6 : {};
1157
1077
  if (type && parent) attach(parent, instance, type);
1158
1078
  if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
1159
1079
  invalidateInstance(instance);
@@ -1518,6 +1438,43 @@ function useStore() {
1518
1438
  function useThree(selector = state => state, equalityFn) {
1519
1439
  return useStore()(selector, equalityFn);
1520
1440
  }
1441
+ function useInject(state) {
1442
+ const useOriginalStore = useStore();
1443
+ const useInjectStore = React.useMemo(() => {
1444
+ const useInjected = (sel = state => state) => {
1445
+ // Execute the useStore hook with the selector once, to maintain reactivity, result doesn't matter
1446
+ useOriginalStore(sel); // Inject data and return the result, either selected or raw
1447
+
1448
+ return sel({ ...useOriginalStore.getState(),
1449
+ ...state
1450
+ });
1451
+ };
1452
+
1453
+ useInjected.setState = useOriginalStore.setState;
1454
+ useInjected.destroy = useOriginalStore.destroy; // Patch getState
1455
+
1456
+ useInjected.getState = () => {
1457
+ return { ...useOriginalStore.getState(),
1458
+ ...state
1459
+ };
1460
+ }; // Patch subscribe
1461
+
1462
+
1463
+ useInjected.subscribe = listener => {
1464
+ return useOriginalStore.subscribe((current, previous) => listener({ ...current,
1465
+ ...state
1466
+ }, previous));
1467
+ };
1468
+
1469
+ return useInjected;
1470
+ }, [useOriginalStore, state]); // Return the patched store and a provider component
1471
+
1472
+ return React.useMemo(() => [({
1473
+ children
1474
+ }) => /*#__PURE__*/React.createElement(context.Provider, {
1475
+ value: useInjectStore
1476
+ }, children), useInjectStore], [useInjectStore]);
1477
+ }
1521
1478
  function useFrame(callback, renderPriority = 0) {
1522
1479
  const subscribe = useStore().getState().internal.subscribe; // Update ref
1523
1480
 
@@ -1681,7 +1638,7 @@ function createRoot(canvas) {
1681
1638
 
1682
1639
  const handleSessionChange = () => {
1683
1640
  const gl = store.getState().gl;
1684
- gl.xr.enabled = gl.xr.isPresenting; // @ts-expect-error
1641
+ gl.xr.enabled = gl.xr.isPresenting; // @ts-ignore
1685
1642
  // WebXRManager's signature is incorrect.
1686
1643
  // See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
1687
1644
 
@@ -1723,6 +1680,7 @@ function createRoot(canvas) {
1723
1680
  } // Set color management
1724
1681
 
1725
1682
 
1683
+ if (THREE.ColorManagement) THREE.ColorManagement.legacyMode = false;
1726
1684
  const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
1727
1685
  const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
1728
1686
  if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
@@ -1838,10 +1796,29 @@ function unmountComponentAtNode(canvas, callback) {
1838
1796
  }
1839
1797
  }
1840
1798
 
1841
- const act = React.unstable_act;
1799
+ function createPortal(children, container, state) {
1800
+ return /*#__PURE__*/React.createElement(Portal, {
1801
+ children: children,
1802
+ container: container,
1803
+ state: state
1804
+ });
1805
+ }
1842
1806
 
1843
- function createPortal(children, container) {
1844
- return reconciler.createPortal(children, container, null, null);
1807
+ function Portal({
1808
+ state,
1809
+ children,
1810
+ container
1811
+ }) {
1812
+ /** This has to be a component because it would not be able to call useThree/useStore otherwise since
1813
+ * if this is our environment, then we are in in r3f's renderer but in react-dom, it would trigger
1814
+ * the "R3F hooks can only be used within the Canvas component!" warning:
1815
+ * <Canvas>
1816
+ * {createPortal(...)} */
1817
+ const portalState = React.useMemo(() => ({ ...state,
1818
+ scene: container
1819
+ }), [state, container]);
1820
+ const [PortalProvider, portalRoot] = useInject(portalState);
1821
+ return /*#__PURE__*/React.createElement(React.Fragment, null, reconciler.createPortal( /*#__PURE__*/React.createElement(PortalProvider, null, children), portalRoot, null));
1845
1822
  }
1846
1823
 
1847
1824
  reconciler.injectIntoDevTools({
@@ -1849,5 +1826,6 @@ reconciler.injectIntoDevTools({
1849
1826
  rendererPackageName: '@react-three/fiber',
1850
1827
  version: '18.0.0'
1851
1828
  });
1829
+ const act = React.unstable_act;
1852
1830
 
1853
- export { createRoot as a, context as b, createEvents as c, createPortal as d, extend as e, reconciler as f, applyProps as g, dispose as h, invalidate as i, advance as j, addEffect as k, addAfterEffect as l, addTail as m, act as n, omit as o, pick as p, roots as q, render as r, useStore as s, threeTypes as t, unmountComponentAtNode as u, useThree as v, useFrame as w, useGraph as x, useLoader as y };
1831
+ export { createRoot as a, context as b, createEvents as c, createPortal as d, extend as e, reconciler as f, applyProps as g, dispose as h, invalidate as i, advance as j, addEffect as k, addAfterEffect as l, addTail as m, act as n, omit as o, pick as p, roots as q, render as r, useStore as s, threeTypes as t, unmountComponentAtNode as u, useThree as v, useInject as w, useFrame as x, useGraph as y, useLoader as z };