feat: unify references and signals (#137)

This commit is contained in:
Jacob
2023-01-18 00:35:02 +01:00
committed by GitHub
parent 81cba5d39d
commit 063aede084
4 changed files with 62 additions and 22 deletions

View File

@@ -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;

View File

@@ -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> {

View File

@@ -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});

View File

@@ -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>;
}