Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #473 from gluestack/patch
Browse files Browse the repository at this point in the history
Patch
  • Loading branch information
ankit-tailor authored Oct 11, 2023
2 parents 9da1c23 + 0d9b166 commit dba8656
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 178 deletions.
2 changes: 1 addition & 1 deletion packages/animation-legend-motion-driver/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gluestack-style/legend-motion-animation-driver",
"version": "1.0.1",
"version": "1.0.2",
"description": "A gluestack-style plugin for animation support using legendapp motion library",
"keywords": [
"react",
Expand Down
108 changes: 22 additions & 86 deletions packages/animation-legend-motion-driver/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,18 @@
import { useStyled } from '@gluestack-style/react';
import type {
IAnimationDriverPlugin,
IAnimationResolver,
} from '@gluestack-style/react';
import React, { useMemo } from 'react';
import {
deepMerge,
deepMergeObjects,
setObjectKeyValue,
resolvedTokenization,
} from './utils';
import React from 'react';
import { deepMerge } from './utils';
import {
Motion,
AnimatePresence as MotionAnimatePresence,
createMotionAnimatedComponent,
} from '@legendapp/motion';
import { MotionSvg } from '@legendapp/motion/svg';
import { propertyTokenMap } from './propertyTokenMap';
import { Pressable } from 'react-native';

function tokenizeAnimationPropsFromConfig(
props: any = {},
config: any,
animationAliases: any,
path: any = [],
tokenizedAnimatedProps: any = {}
) {
for (const prop in props) {
if (Array.isArray(props[prop])) {
path.push(prop);
setObjectKeyValue(tokenizedAnimatedProps, path, props[prop]);
path.pop();
} else if (animationAliases[prop]) {
path.push(prop);
const tokenizedValue = resolvedTokenization(props[prop], config);
setObjectKeyValue(tokenizedAnimatedProps, path, tokenizedValue);
path.pop();
} else if (typeof props[prop] === 'object') {
path.push(prop);
const tokenizedValue = resolvedTokenization(props[prop], config);
setObjectKeyValue(tokenizedAnimatedProps, path, tokenizedValue);
// path.pop();
tokenizeAnimationPropsFromConfig(
props[prop],
config,
animationAliases,
path,
tokenizedAnimatedProps
);
path.pop();
} else {
path.push(prop);
setObjectKeyValue(tokenizedAnimatedProps, path, props[prop]);
path.pop();
}
}

return tokenizedAnimatedProps;
}

function getVariantProps(props: any, theme: any) {
const variantTypes = theme?.variants ? Object.keys(theme.variants) : [];

Expand Down Expand Up @@ -91,65 +46,38 @@ function resolveVariantAnimationProps(variantProps: any, styledObject: any) {

const AnimatePresence = React.forwardRef(
({ children, ...props }: any, ref?: any) => {
const ctx = useStyled();
const clonedChildren: any = [];
const CONFIG = useMemo(
() => ({
...ctx.config,
propertyTokenMap,
}),
[ctx.config]
);

React.Children.toArray(children).forEach((child: any) => {
if (
(child?.type?.displayName &&
child?.type?.displayName.includes('Gluestack-AnimatedResolver')) ||
child?.type?.isStyledComponent
) {
let tokenizedAnimatedProps: any = {};
const animationAliases = {};

const componentStyledObject = child?.type?.getStyledData()?.config;

const { variantProps, restProps } = getVariantProps(
child?.props,
{ ...componentStyledObject?.props, ...child?.props },
componentStyledObject
);

const config = CONFIG;

const variantStyledObject = resolveVariantAnimationProps(
const variantStyledObject: any = resolveVariantAnimationProps(
variantProps,
componentStyledObject
);

const componentStyledObjectWithVariants = deepMergeObjects(
componentStyledObject,
variantStyledObject
);
tokenizedAnimatedProps = tokenizeAnimationPropsFromConfig(
componentStyledObjectWithVariants,
config,
animationAliases
);

const tokenizedSxAnimationProps: any = tokenizeAnimationPropsFromConfig(
child?.props?.sx,
config,
animationAliases
);

const mergedAnimatedProps = deepMergeObjects(
{},
tokenizedSxAnimationProps,
tokenizedAnimatedProps
);
const exit = {
...componentStyledObject?.[':exit'],
...variantStyledObject?.[':exit'],
...restProps?.sx?.[':exit'],
...restProps?.exit,
};

const clonedChild = React.cloneElement(child, {
exit,
...restProps,
exit: mergedAnimatedProps?.baseStyle?.[':exit'],
});

clonedChildren.push(clonedChild);
} else {
clonedChildren.push(child);
Expand All @@ -167,9 +95,17 @@ const AnimatePresence = React.forwardRef(
const AnimatedPressable = createMotionAnimatedComponent(
Pressable
) as React.ComponentType<typeof Pressable>;

const MotionComponents = {
...Motion,
...MotionSvg,
Pressable: AnimatedPressable,
AnimatePresence,
};

export class MotionAnimationDriver implements IAnimationDriverPlugin {
name: 'MotionAnimationDriver';
engine = { ...Motion, Pressable: AnimatedPressable, AnimatePresence };
engine = MotionComponents;
config = {
aliases: {
':animate': 'animate',
Expand Down
2 changes: 1 addition & 1 deletion packages/animation-moti-driver/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gluestack-style/moti-animation-driver",
"version": "1.0.1",
"version": "1.0.2",
"description": "A gluestack-style driver for using moti animation with animation resolver plugin.",
"keywords": [
"react",
Expand Down
37 changes: 37 additions & 0 deletions packages/animation-moti-driver/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,32 @@ import {
MotiProgressBar,
AnimatePresence,
} from 'moti';
import {
Svg as RNSvg,
Rect as RNRect,
Circle as RNCircle,
Ellipse as RNEllipse,
Line as RNLine,
Polyline as RNPolyline,
Path as RNPath,
TSpan as RNTSpan,
TextPath as RNTextPath,
G as RNG,
ClipPath as RNClipPath,
} from 'react-native-svg';
import { motifySvg } from 'moti/svg';

const Svg = motifySvg(RNSvg);
const Rect = motifySvg(RNRect);
const Circle = motifySvg(RNCircle);
const Ellipse = motifySvg(RNEllipse);
const Line = motifySvg(RNLine);
const Polyline = motifySvg(RNPolyline);
const Path = motifySvg(RNPath);
const TSpan = motifySvg(RNTSpan);
const TextPath = motifySvg(RNTextPath);
const G = motifySvg(RNG);
const ClipPath = motifySvg(RNClipPath);

let Moti = {
Image: MotiImage,
Expand All @@ -21,6 +47,17 @@ let Moti = {
ScrollView: MotiScrollView,
SafeAreaView: MotiSafeAreaView,
ProgressBar: MotiProgressBar,
Svg,
Rect,
Circle,
Ellipse,
Line,
Polyline,
Path,
TSpan,
TextPath,
G,
ClipPath,
AnimatePresence,
};
export class MotiAnimationDriver implements IAnimationDriverPlugin {
Expand Down
2 changes: 1 addition & 1 deletion packages/animation-resolver/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gluestack-style/animation-resolver",
"version": "1.0.1",
"version": "1.0.2",
"description": "A gluestack-style plugin for resolving animation properties, utilizing animation libraries.",
"keywords": [
"react",
Expand Down
126 changes: 125 additions & 1 deletion packages/animation-resolver/src/AnimatedComponents/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ import type {
FlatListProps,
SectionListProps,
} from 'react-native';
import type {
SvgProps,
GProps,
ClipPathProps,
RectProps,
PolylineProps,
CircleProps,
EllipseProps,
LineProps,
PathProps,
TSpanProps,
TextPathProps,
} from 'react-native-svg';

const getAnimationResolverPlugin: any = (plugins: any[]) => {
let pluginData;
plugins.forEach((plugin) => {
plugins?.forEach((plugin) => {
if (plugin.name === 'AnimationResolver') {
pluginData = plugin;
}
Expand Down Expand Up @@ -94,6 +107,95 @@ const AnimatedSectionList = (
const Component = animatedComponent('SectionList', props);
return <Component {...props} />;
};

const AnimatedSvg = (
props: SvgProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Svg', props);
return <Component {...props} />;
};
const AnimatedRect = (
props: RectProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Rect', props);
return <Component {...props} />;
};
const AnimatedCircle = (
props: CircleProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Circle', props);
return <Component {...props} />;
};
const AnimatedEllipse = (
props: EllipseProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Ellipse', props);
return <Component {...props} />;
};
const AnimatedLine = (
props: LineProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Line', props);
return <Component {...props} />;
};
const AnimatedPolyline = (
props: PolylineProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Polyline', props);
return <Component {...props} />;
};
const AnimatedPath = (
props: PathProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('Path', props);
return <Component {...props} />;
};
const AnimatedTSpan = (
props: TSpanProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('TSpan', props);
return <Component {...props} />;
};
const AnimatedTextPath = (
props: TextPathProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('TextPath', props);
return <Component {...props} />;
};
const AnimatedG = (
props: GProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('G', props);
return <Component {...props} />;
};
const AnimatedClipPath = (
props: ClipPathProps & {
animationComponentGluestack: true;
}
) => {
const Component = animatedComponent('ClipPath', props);
return <Component {...props} />;
};
const AnimatePresence = animatedComponent('AnimatePresence', {});

AnimatedText.displayName = 'Gluestack-AnimatedResolver-AnimatedText';
Expand All @@ -109,6 +211,17 @@ AnimatedSectionList.displayName =
'Gluestack-AnimatedResolver-AnimatedSectionList';
AnimatePresence.displayName =
'Gluestack-AnimatedResolver-AnimatedAnimatePresence';
AnimatedSvg.displayName = 'Gluestack-AnimatedResolver-AnimatedSvg';
AnimatedRect.displayName = 'Gluestack-AnimatedResolver-AnimatedRect';
AnimatedCircle.displayName = 'Gluestack-AnimatedResolver-AnimatedCircle';
AnimatedEllipse.displayName = 'Gluestack-AnimatedResolver-AnimatedEllipse';
AnimatedLine.displayName = 'Gluestack-AnimatedResolver-AnimatedLine';
AnimatedPolyline.displayName = 'Gluestack-AnimatedResolver-AnimatedPolyline';
AnimatedPath.displayName = 'Gluestack-AnimatedResolver-AnimatedPath';
AnimatedTSpan.displayName = 'Gluestack-AnimatedResolver-AnimatedTSpan';
AnimatedTextPath.displayName = 'Gluestack-AnimatedResolver-AnimatedTextPath';
AnimatedG.displayName = 'Gluestack-AnimatedResolver-AnimatedG';
AnimatedClipPath.displayName = 'Gluestack-AnimatedResolver-AnimatedClipPath';

export {
AnimatedText,
Expand All @@ -120,4 +233,15 @@ export {
AnimatedFlatList,
AnimatedSectionList,
AnimatePresence,
AnimatedSvg,
AnimatedRect,
AnimatedCircle,
AnimatedEllipse,
AnimatedLine,
AnimatedPolyline,
AnimatedPath,
AnimatedTSpan,
AnimatedTextPath,
AnimatedG,
AnimatedClipPath,
};
Loading

0 comments on commit dba8656

Please sign in to comment.