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 #91 from gluestack/release/@dank-style/convert-uti…
Browse files Browse the repository at this point in the history
…lity-to-sx/@0.1.7

Release/@dank style/convert utility to sx/@0.1.7
  • Loading branch information
surajahmed authored Mar 23, 2023
2 parents 0b321c1 + f851bba commit f03752e
Show file tree
Hide file tree
Showing 16 changed files with 884 additions and 130 deletions.
28 changes: 28 additions & 0 deletions packages/animation-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
.pnp
.pnp.js

# misc
.DS_Store
*.pem

# build
dist
lib

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# turbo
.turbo
1 change: 1 addition & 0 deletions packages/animation-plugin/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16.13.0
22 changes: 22 additions & 0 deletions packages/animation-plugin/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
process.env.NODE_ENV !== 'production'
? [
'module-resolver',
{
alias: {
// For development, we want to alias the library to the source
['@dank-style/react']: path.join(
__dirname,
'../react/src/index'
),
},
},
]
: ['transform-remove-console'],
],
};
};
46 changes: 46 additions & 0 deletions packages/animation-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@dank-style/animation-plugin",
"version": "0.0.1",
"main": "lib/commonjs/index",
"types": "lib/typescript/index.d.ts",
"module": "lib/module/index",
"react-native": "src/index",
"source": "src/index",
"typings": "lib/typescript/index.d.ts",
"scripts": {
"prepare": "bob build",
"release": "release-it",
"build": "bob build",
"clean": "rm -rf lib"
},
"dependencies": {
"@dank-style/react": "0.3.6"
},
"devDependencies": {
"@types/lodash.merge": "^4.6.7",
"@types/react": "^18.0.22",
"@types/react-native": "^0.69.15",
"babel-plugin-transform-remove-console": "^6.9.4",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-native": "^0.70.3",
"react-native-builder-bob": "^0.20.1",
"tsconfig": "*",
"typescript": "^4.7.4"
},
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
[
"module"
],
"typescript"
]
},
"files": [
"lib/",
"src/"
]
}
294 changes: 294 additions & 0 deletions packages/animation-plugin/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
import React, { useMemo } from 'react';
import type { IStyled, IStyledPlugin } from '@dank-style/react';
import { useStyled } from '@dank-style/react';
import {
deepMerge,
deepMergeObjects,
setObjectKeyValue,
resolvedTokenization,
} from './utils';
import { AnimatePresence } from '@legendapp/motion';
import { propertyTokenMap } from './propertyTokenMap';

function tokenizeAnimationPropsFromConfig(
props: any = {},
config: any,
animationAliases: any,
path: any = [],
tokenizedAnimatedProps: any = {}
) {
for (const prop in props) {
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;
}

export class AnimationResolver implements IStyledPlugin {
name: 'AnimationResolver';
styledUtils: IStyled | undefined = {
aliases: {
':animate': 'animate',
':initial': 'initial',
':exit': 'exit',
':initialProps': 'initialProps',
':animateProps': 'animateProps',
':transition': 'transition',
':transformOrigin': 'transformOrigin',
':whileTap': 'whileTap',
':whileHover': 'whileHover',
':onAnimationComplete': 'onAnimationComplete',
},
};

register(styledUtils: any) {
if (this.styledUtils) {
this.styledUtils.aliases = {
...this.styledUtils?.aliases,
...styledUtils?.aliases,
};

this.styledUtils.tokens = {
...this.styledUtils?.tokens,
...styledUtils?.tokens,
};

this.styledUtils.ref = styledUtils?.ref;
}
}

constructor(styledUtils?: IStyled) {
this.register(styledUtils);
this.name = 'AnimationResolver';
}

#childrenExitPropsMap: any = {};

#extendedConfig: any = {};

inputMiddleWare(styledObj: any = {}, shouldUpdateConfig: any = true) {
// this.#childrenExitPropsMap = deepClone(styledObj);

const resolvedAnimatedProps = this.updateStyledObject(
styledObj,
shouldUpdateConfig
);
const resolvedStyledObjectWithAnimatedProps = deepMergeObjects(
resolvedAnimatedProps,
styledObj
);

if (shouldUpdateConfig) {
return styledObj;
}

return resolvedStyledObjectWithAnimatedProps;
}

updateStyledObject(
styledObject: any = {},
shouldUpdateConfig: boolean,
resolvedStyledObject: any = {},
keyPath: string[] = []
) {
const aliases = this.styledUtils?.aliases;
for (const prop in styledObject) {
if (typeof styledObject[prop] === 'object') {
keyPath.push(prop);
this.updateStyledObject(
styledObject[prop],
shouldUpdateConfig,
resolvedStyledObject,
keyPath
);
keyPath.pop();
}

if (aliases && aliases?.[prop]) {
if (shouldUpdateConfig) {
this.#childrenExitPropsMap[prop] = styledObject[prop];
}
const value = styledObject[prop];
keyPath.push('props', aliases[prop]);
setObjectKeyValue(resolvedStyledObject, keyPath, value);
keyPath.pop();
keyPath.pop();
delete styledObject[prop];
}
}

return resolvedStyledObject;
}

componentMiddleWare({ NewComp, extendedConfig }: any) {
const styledConfig = this.#childrenExitPropsMap;

this.#childrenExitPropsMap = {};

const Component = React.forwardRef((props: any, ref: any) => {
const { sx, ...restProps } = props;

const styledContext = useStyled();
const CONFIG = useMemo(
() => ({
...styledContext.config,
propertyTokenMap,
}),
[styledContext.config]
);
this.#extendedConfig = CONFIG;
if (extendedConfig) {
this.#extendedConfig = deepMerge(CONFIG, extendedConfig);
}

let tokenizedAnimatedProps: any = {};
const componentStyledObject = styledConfig;

const animationAliases = this.styledUtils?.aliases;

const config = this.#extendedConfig;

tokenizedAnimatedProps = tokenizeAnimationPropsFromConfig(
componentStyledObject,
config,
animationAliases
);

const tokenizedSxAnimationProps: any = tokenizeAnimationPropsFromConfig(
sx,
config,
animationAliases
);

const mergedAnimatedProps = deepMerge(
tokenizedAnimatedProps,
tokenizedSxAnimationProps
);

const resolvedAnimatedStyledWithStyledObject = this.inputMiddleWare(
mergedAnimatedProps,
false
);

let isState = false;

Object.keys(restProps?.states ?? {}).forEach((state: any) => {
isState = restProps.states[state] ? true : false;
});

const animatedProps = !isState
? resolvedAnimatedStyledWithStyledObject?.props
: {};

return (
<NewComp
{...animatedProps}
sx={resolvedAnimatedStyledWithStyledObject}
{...restProps}
ref={ref}
/>
);
});

//@ts-ignore
Component.styled = {};
//@ts-ignore
Component.styled.config = {};
//@ts-ignore
Component.styled.config = styledConfig;

Component.displayName = 'DankStyledComponent';

return Component;
}

wrapperComponentMiddleWare() {
const AnimatedPresenceComp = React.forwardRef(
({ children, ...props }: any) => {
const clonedChildren: any = [];
const styledContext = useStyled();
const CONFIG = useMemo(
() => ({
...styledContext.config,
propertyTokenMap,
}),
[styledContext.config]
);

this.#extendedConfig = CONFIG;

React.Children.toArray(children).forEach((child: any) => {
if (child?.type?.displayName === 'DankStyledComponent') {
let tokenizedAnimatedProps: any = {};
const componentStyledObject = child?.type?.styled?.config;
const animationAliases = this.styledUtils?.aliases;

const config = CONFIG;

if (child.type.styled.resolvedProps) {
tokenizedAnimatedProps = child?.type?.styled?.resolvedProps;
} else {
tokenizedAnimatedProps = tokenizeAnimationPropsFromConfig(
componentStyledObject,
config,
animationAliases
);

child.type.styled.resolvedProps = tokenizedAnimatedProps;
}

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

const mergedAnimatedProps = deepMergeObjects(
{},
tokenizedSxAnimationProps,
tokenizedAnimatedProps
);

const clonedChild = React.cloneElement(child, {
...mergedAnimatedProps,
exit: mergedAnimatedProps?.[':exit'],
...child?.props,
});
clonedChildren.push(clonedChild);
} else {
clonedChildren.push(child);
}
});

return <AnimatePresence {...props}>{clonedChildren}</AnimatePresence>;
}
);

AnimatedPresenceComp.displayName = `AnimatePresence`;

return AnimatedPresenceComp;
}
}
Loading

0 comments on commit f03752e

Please sign in to comment.