Skip to content

Commit

Permalink
removing generics
Browse files Browse the repository at this point in the history
  • Loading branch information
mattgperry committed Nov 19, 2018
1 parent 86d1ffc commit 4c61c4d
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 30 deletions.
3 changes: 2 additions & 1 deletion dev/examples/test.tsx
@@ -1,7 +1,8 @@
import * as React from 'react';

export class App extends React.Component {
render() {
// I've had to return `any` here, I thought this was usually inferred?
render(): any {
return null;
}
}
8 changes: 4 additions & 4 deletions src/hooks/use-config.ts
@@ -1,16 +1,16 @@
import { useMemo } from 'react';
import {
MotionConfig,
MotionConfigResolver,
MotionConfigFactory,
MotionProps
} from '../motion/types';

const isResolver = (
config: MotionConfig | MotionConfigResolver
): config is MotionConfigResolver => typeof config === 'function';
config: MotionConfig | MotionConfigFactory
): config is MotionConfigFactory => typeof config === 'function';

const useConfig = (
baseConfig: MotionConfig | MotionConfigResolver,
baseConfig: MotionConfig | MotionConfigFactory,
props: MotionProps
) =>
useMemo(() => (isResolver(baseConfig) ? baseConfig(props) : baseConfig), []);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/use-motion-value.ts
@@ -0,0 +1,4 @@
import { useMemo } from 'react';
import motionValue from '../motion-value';

export default (init: number | string) => useMemo(() => motionValue(init), []);
17 changes: 17 additions & 0 deletions src/hooks/use-pose.ts
@@ -0,0 +1,17 @@
import { useMemo } from 'react';
import motionValue from '../motion-value';
import { poseToArray } from '../utils/pose-resolvers';

const usePose = (initPose = 'default') => {
return useMemo(() => {
const pose = motionValue(initPose, {
transformer: (v: string | string[]) => poseToArray(v)
});

const setPose = (newPose: string | string[]) => pose.set(newPose);

return [pose, setPose];
}, []);
};

export default usePose;
8 changes: 4 additions & 4 deletions src/hooks/use-posed-values.ts
Expand Up @@ -4,11 +4,11 @@ import { MotionConfig, MotionProps } from '../motion/types';
import { useRef, useEffect, RefObject } from 'react';
import styler from 'stylefire';

export default <P extends object>(
export default (
config: MotionConfig,
props: P & MotionProps,
props: MotionProps,
ref: RefObject<Element>
): [Map<string, MotionValue>, P & MotionProps] => {
): [Map<string, MotionValue>, Partial<MotionProps>] => {
const values = useRef(new Map()).current;
const returnedProps = {};

Expand Down Expand Up @@ -51,7 +51,7 @@ export default <P extends object>(
const domStyler = styler(ref.current);

values.forEach((value, key) => {
value.setOnRender(v => domStyler.set(key, v));
value.setOnRender((v: any) => domStyler.set(key, v));
});

return () => values.forEach(value => value.destroy());
Expand Down
5 changes: 4 additions & 1 deletion src/hooks/use-style-attr.ts
Expand Up @@ -2,7 +2,10 @@ import { useMemo, CSSProperties } from 'react';
import { buildStyleProperty } from 'stylefire';
import { MotionValue } from '../motion-value';

export default (styles: CSSProperties, values: Map<string, MotionValue>) =>
export default (
values: Map<string, MotionValue>,
styles?: CSSProperties
): CSSProperties =>
useMemo(() => {
const resolvedValues = Object.keys(values).reduce((acc, key) => {
acc[key] = values[key].get();
Expand Down
2 changes: 1 addition & 1 deletion src/motion-value/index.ts
@@ -1,7 +1,7 @@
import sync from 'framesync';
import { Action, ColdSubscription } from 'popmotion';

export type ValuePrimitive = number | string;
export type ValuePrimitive = any;

export type Transformer = (v: ValuePrimitive) => ValuePrimitive;

Expand Down
37 changes: 25 additions & 12 deletions src/motion/component.ts
@@ -1,29 +1,42 @@
import { memo, forwardRef, createElement, Ref, ComponentType } from 'react';
import { MotionProps, MotionConfig, MotionConfigResolver } from './types';
import {
memo,
forwardRef,
createElement,
Ref,
ComponentType,
createRef,
HTMLProps,
SVGProps
} from 'react';
import { MotionProps, ComponentFactory } from './types';
import useConfig from '../hooks/use-config';
import useExternalRef from '../hooks/use-external-ref';
import usePosedValues from '../hooks/use-posed-values';
import usePoseResolver from '../hooks/use-pose-resolver';
import useStyleAttr from '../hooks/use-style-attr';

const createMotionComponent = <P extends object>(
Component: ComponentType<P> | string
) => (motionConfig: MotionConfig | MotionConfigResolver) => {
const createMotionComponent = (
Component: string | ComponentType
): ComponentFactory => motionConfig => {
const MotionComponent = forwardRef(
(props: P & MotionProps, externalRef?: Ref<Element>) => {
(props: MotionProps, externalRef?: Ref<Element>) => {
const ref = useExternalRef(externalRef);
const config = useConfig(motionConfig, props);

// Create motion values
const [values, componentProps] = usePosedValues<P>(config, props, ref);
const [values, componentProps] = usePosedValues(config, props, ref);

usePoseResolver(values, config, props);

return createElement(Component, {
ref,
...componentProps,
style: useStyleAttr(props.styles, values)
});
// Types here are a bit of a hack
return createElement<HTMLProps<any> | SVGProps<any> & MotionProps>(
Component,
{
ref: createRef(),
...componentProps,
style: useStyleAttr(values, props.style)
}
);
}
);

Expand Down
3 changes: 2 additions & 1 deletion src/motion/index.ts
@@ -1,7 +1,8 @@
import createMotionComponent from './component';
import supportedElements from './supported-elements';
import { Motion } from './types';

const motion = createMotionComponent;
const motion: Motion = createMotionComponent as Motion;

supportedElements.forEach(
element => (motion[element] = createMotionComponent(element))
Expand Down
25 changes: 19 additions & 6 deletions src/motion/types.ts
@@ -1,7 +1,26 @@
import { MotionValue } from '../motion-value';
import { RefObject, CSSProperties, ComponentType } from 'react';

export type MotionConfigFactory = (props: MotionProps) => MotionConfig;

export type ComponentFactory = (
config?: MotionConfigFactory | MotionConfig
) => ComponentType;

export type Motion = {
(component: ComponentType): ComponentFactory;
[key: string]: ComponentFactory;
};

export type MotionConfig = {
[key: string]: Pose | PoseResolver;
};

export type MotionProps = {
[key: string]: any;
ref: RefObject<Element>;
pose: string | string[] | MotionValue;
style: CSSProperties;
};

export type Tween = {};
Expand Down Expand Up @@ -31,9 +50,3 @@ export type Pose = PoseSettings & {
};

export type PoseResolver = (props: { [key: string]: any }) => Pose;

export type MotionConfig = {
[key: string]: Pose | PoseResolver;
};

export type MotionConfigResolver = (props: MotionProps) => MotionConfig;

0 comments on commit 4c61c4d

Please sign in to comment.