mirror of
https://github.com/motion-canvas/motion-canvas.git
synced 2026-01-11 23:07:57 -05:00
feat: unify references and signals (#137)
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
||||
Vector2Signal,
|
||||
ColorSignal,
|
||||
} from '@motion-canvas/core/lib/types';
|
||||
import {Reference} from '@motion-canvas/core/lib/utils';
|
||||
import {ReferenceReceiver} from '@motion-canvas/core/lib/utils';
|
||||
import type {ComponentChild, ComponentChildren, NodeConstructor} from './types';
|
||||
import {Promisable} from '@motion-canvas/core/lib/threading';
|
||||
import {useScene2D} from '../scenes/useScene2D';
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
} from '@motion-canvas/core/lib/signals';
|
||||
|
||||
export interface NodeProps {
|
||||
ref?: Reference<any>;
|
||||
ref?: ReferenceReceiver<any>;
|
||||
children?: ComponentChildren;
|
||||
key?: string;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {Node} from './Node';
|
||||
import type {Reference} from '@motion-canvas/core/lib/utils';
|
||||
import type {ReferenceReceiver} from '@motion-canvas/core/lib/utils';
|
||||
|
||||
export type ComponentChild =
|
||||
| Node
|
||||
@@ -22,7 +22,7 @@ export type PropsOf<T> = T extends NodeConstructor<infer P>
|
||||
|
||||
export interface JSXProps {
|
||||
children?: ComponentChildren;
|
||||
ref?: Reference<Node>;
|
||||
ref?: ReferenceReceiver<Node>;
|
||||
}
|
||||
|
||||
export interface FunctionComponent<T = any> {
|
||||
|
||||
@@ -35,9 +35,7 @@ export function jsx(
|
||||
|
||||
if (isClassComponent(type)) {
|
||||
const node = new type({...rest, children: flatChildren});
|
||||
if (ref) {
|
||||
ref.value = node;
|
||||
}
|
||||
ref?.(node);
|
||||
return node;
|
||||
} else {
|
||||
return type({...rest, ref, children: flatChildren});
|
||||
|
||||
@@ -1,23 +1,65 @@
|
||||
export type Reference<TValue> = TValue extends (config: {
|
||||
ref?: infer TReference;
|
||||
}) => void
|
||||
? TReference
|
||||
: {value: TValue};
|
||||
import {deprecate} from './deprecate';
|
||||
|
||||
export interface ReferenceReceiver<T> {
|
||||
(reference: T): void;
|
||||
}
|
||||
|
||||
export interface Reference<T> extends ReferenceReceiver<T> {
|
||||
(): T;
|
||||
|
||||
/**
|
||||
* @deprecated Invoke the reference instead.
|
||||
*/
|
||||
value: T;
|
||||
}
|
||||
|
||||
export function createRef<T>(): Reference<T> {
|
||||
return {} as Reference<T>;
|
||||
let value: T;
|
||||
const ref = (newValue?: T) => {
|
||||
if (newValue !== undefined) {
|
||||
value = newValue;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(ref, 'value', {
|
||||
get: deprecate(
|
||||
() => value,
|
||||
'get Reference.value has been deprecated.',
|
||||
`To retrieve the referenced object, invoke the reference like a function:
|
||||
<pre>ref.value; // wrong\nref(); // correct</pre>`,
|
||||
),
|
||||
set: deprecate(
|
||||
newValue => {
|
||||
value = newValue;
|
||||
},
|
||||
'set Reference.value has been deprecated.',
|
||||
`To set the referenced object, pass it to the reference like you would to a function:
|
||||
<pre>ref.value = object; // wrong\nref(object); // correct</pre>`,
|
||||
),
|
||||
});
|
||||
|
||||
return ref as Reference<T>;
|
||||
}
|
||||
|
||||
export function makeRef<TObject, TKey extends keyof TObject>(
|
||||
object: TObject,
|
||||
key: TKey,
|
||||
): Reference<TObject[TKey]> {
|
||||
return {
|
||||
get value(): TObject[TKey] {
|
||||
return object[key];
|
||||
},
|
||||
set value(value: TObject[TKey]) {
|
||||
object[key] = value;
|
||||
},
|
||||
} as Reference<TObject[TKey]>;
|
||||
): ReferenceReceiver<TObject[TKey]> {
|
||||
return newValue => {
|
||||
object[key] = newValue;
|
||||
};
|
||||
}
|
||||
|
||||
export type RefsProperty<TValue> = TValue extends (config: {
|
||||
refs?: infer TReference;
|
||||
}) => void
|
||||
? TReference
|
||||
: never;
|
||||
|
||||
export function makeRefs<
|
||||
T extends (config: {refs?: any}) => void,
|
||||
>(): RefsProperty<T> {
|
||||
return {} as RefsProperty<T>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user