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

Commit

Permalink
feat: new plugin architecture with animation plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
rayan1810 committed Sep 13, 2023
1 parent e07a894 commit 0ac5a16
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 58 deletions.
1 change: 0 additions & 1 deletion example/storybook/src/components/nb.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,6 @@ export const config = createConfig({
},
},
},
plugins: [new AnimationResolver({})],
} as const);

type ConfigType = typeof config;
Expand Down
74 changes: 42 additions & 32 deletions example/storybook/src/plugins/AnimationPlugin/AnimationPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@ import React from 'react';
import { Wrapper } from '../../components/Wrapper';
import { Motion } from '@legendapp/motion';
import { Pressable, View } from 'react-native';
import { styled } from '@gluestack-style/react';
import { FontResolver, styled } from '@gluestack-style/react';
import { AnimationResolver } from '@gluestack-style/animation-plugin';

const images = [require('./1.png'), require('./2.png'), require('./3.png')];

const Box = styled(View, {});

const StyledMotionImage = styled(Motion.Image, {
':animate': {
zIndex: 1,
x: 0,
opacity: 1,
const StyledMotionImage = styled(
Motion.Image,
{
':animate': {
zIndex: 1,
x: 0,
opacity: 1,
},
},
});
{},
{
plugins: [new AnimationResolver({})],
}
);

export function AnimationPlugin() {
const [imageIndex, setImageIndex] = React.useState(0);
Expand All @@ -35,31 +42,34 @@ export function AnimationPlugin() {
'aspectRatio': 1 * 1.4,
}}
>
{/* <styled.Component> */}
<StyledMotionImage
style={{
width: '100%',
height: '100%',
position: 'absolute',
}}
source={{ uri: images[imageIndex] }}
key={`image-${imageIndex}-${Math.random()}`}
sx={{
':initial': {
x: xPosition,
opacity: 0,
},
':exit': {
zIndex: 0,
x: -xPosition,
opacity: 0,
},
':transition': {
x: { type: 'spring', stiffness: 200, damping: 23 },
},
}}
/>
{/* </styled.Component> */}
{/* @ts-ignore */}
<StyledMotionImage.AnimatePresence>
<StyledMotionImage
style={{
width: '100%',
height: '100%',
position: 'absolute',
}}
source={{ uri: images[imageIndex] }}
key={`image-${imageIndex}-${Math.random()}`}
sx={{
// @ts-ignore
':initial': {
x: xPosition,
opacity: 0,
},
':exit': {
zIndex: 0,
x: -xPosition,
opacity: 0,
},
':transition': {
x: { type: 'spring', stiffness: 200, damping: 23 },
},
}}
/>
{/* @ts-ignore */}
</StyledMotionImage.AnimatePresence>
</Box>
<Pressable
accessibilityRole="button"
Expand Down
3 changes: 3 additions & 0 deletions example/storybook/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"baseUrl": ".",
"paths": {
"@gluestack-style/react": ["../../packages/react/src"],
"@gluestack-style/animation-plugin": [
"../../packages/animation-plugin/src"
],
"react-native": ["./node_modules/react-native-web"]
},
"emitDeclarationOnly": true,
Expand Down
23 changes: 17 additions & 6 deletions packages/animation-plugin/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function resolveVariantAnimationProps(variantProps: any, styledObject: any) {

export class AnimationResolver implements IStyledPlugin {
name: 'AnimationResolver';
styledUtils: IStyled | undefined = {
styledUtils = {
aliases: {
':animate': 'animate',
':initial': 'initial',
Expand All @@ -95,7 +95,7 @@ export class AnimationResolver implements IStyledPlugin {
':whileTap': 'whileTap',
':whileHover': 'whileHover',
':onAnimationComplete': 'onAnimationComplete',
},
} as const,
};

register(styledUtils: any) {
Expand All @@ -105,11 +105,14 @@ export class AnimationResolver implements IStyledPlugin {
...styledUtils?.aliases,
};

// @ts-ignore
this.styledUtils.tokens = {
// @ts-ignore
...this.styledUtils?.tokens,
...styledUtils?.tokens,
};

// @ts-ignore
this.styledUtils.ref = styledUtils?.ref;
}
}
Expand All @@ -123,9 +126,14 @@ export class AnimationResolver implements IStyledPlugin {

#extendedConfig: any = {};

inputMiddleWare(styledObj: any = {}, shouldUpdateConfig: any = true) {
inputMiddleWare<P>(
styledObj = {},
shouldUpdateConfig: any = true
): {
// @ts-ignore
[key in keyof typeof this.styledUtils.aliases]: P[(typeof this.styledUtils.aliases)[key]];
} {
// this.#childrenExitPropsMap = deepClone(styledObj);

const resolvedAnimatedProps = this.updateStyledObject(
styledObj,
shouldUpdateConfig
Expand All @@ -136,6 +144,7 @@ export class AnimationResolver implements IStyledPlugin {
);

if (shouldUpdateConfig) {
// @ts-ignore
return styledObj;
}

Expand All @@ -161,6 +170,7 @@ export class AnimationResolver implements IStyledPlugin {
keyPath.pop();
}

// @ts-ignore
if (aliases && aliases?.[prop]) {
if (shouldUpdateConfig) {
// this.#childrenExitPropsMap[prop] = styledObject[prop];
Expand All @@ -171,6 +181,7 @@ export class AnimationResolver implements IStyledPlugin {
);
}
const value = styledObject[prop];
// @ts-ignore
keyPath.push('props', aliases[prop]);
setObjectKeyValue(resolvedStyledObject, keyPath, value);
keyPath.pop();
Expand Down Expand Up @@ -245,9 +256,9 @@ export class AnimationResolver implements IStyledPlugin {
Object.keys(restProps?.states ?? {}).forEach((state: any) => {
isState = restProps.states[state] ? true : false;
});

const animatedProps = !isState
? resolvedAnimatedStyledWithStyledObject?.props
? // @ts-ignore
resolvedAnimatedStyledWithStyledObject?.props
: {};

return (
Expand Down
26 changes: 18 additions & 8 deletions packages/react/src/styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1824,11 +1824,11 @@ export function verboseStyled<P, Variants, ComCon>(
return StyledComp;
}

export function styled<P, Variants, ComCon>(
export function styled<P, Variants, ComCon, PluginType = []>(
Component: React.ComponentType<P>,
theme: ITheme<Variants, P>,
theme: ITheme<Variants, P, PluginType>,
componentStyleConfig?: IComponentStyleConfig<ComCon>,
ExtendedConfig?: ExtendedConfigType,
ExtendedConfig?: ExtendedConfigType<PluginType>,
BUILD_TIME_PARAMS?: {
orderedResolved: OrderedSXResolved;
verbosedStyleIds: {
Expand All @@ -1843,12 +1843,17 @@ export function styled<P, Variants, ComCon>(
// const DEBUG =
// process.env.NODE_ENV === 'development' && DEBUG_TAG ? false : false;

let styledObj: any = theme;

const plugins = getInstalledPlugins();
let styledObj = theme;
// @ts-ignore
let plugins: PluginType = [...getInstalledPlugins()];
if (ExtendedConfig?.plugins) {
// @ts-ignore
plugins = [...plugins, ...ExtendedConfig?.plugins];
}

for (const pluginName in plugins) {
styledObj = plugins[pluginName]?.inputMiddleWare(styledObj, true, true);
// @ts-ignore
styledObj = plugins[pluginName]?.inputMiddleWare<P>(styledObj, true, true);
}
theme = styledObj;
const sxConvertedObject = convertStyledToStyledVerbosed(theme);
Expand All @@ -1860,9 +1865,12 @@ export function styled<P, Variants, ComCon>(
ExtendedConfig,
BUILD_TIME_PARAMS
);
// @ts-ignore
plugins?.reverse();
for (const pluginName in plugins) {
// @ts-ignore
if (plugins[pluginName]?.componentMiddleWare) {
// @ts-ignore
StyledComponent = plugins[pluginName]?.componentMiddleWare({
Component: StyledComponent,
theme,
Expand All @@ -1874,8 +1882,10 @@ export function styled<P, Variants, ComCon>(

for (const pluginName in plugins) {
const compWrapper =
// @ts-ignore
typeof plugins[pluginName].wrapperComponentMiddleWare === 'function'
? plugins[pluginName].wrapperComponentMiddleWare()
? // @ts-ignore
plugins[pluginName].wrapperComponentMiddleWare()
: null;

if (compWrapper) {
Expand Down
42 changes: 31 additions & 11 deletions packages/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,16 @@ export type CreateConfig = {
globalStyle?: CreateGenericConfig['globalStyle'];
};

export type ThemeStyles<Tokens> = {
// @ts-ignore
[key: string]: Tokens;
};
export type ThemeStyles<IToken> = Partial<{
[key: string]: {
[key in keyof IToken]?: {
// @ts-ignore
[k in `$${keyof IToken[key]}`]?: // @ts-ignore
| `$${key}$${keyof IToken[key]}`
| (String & {});
};
};
}>;

// Generic Creator
export type GlueStackConfig<
Expand All @@ -78,7 +84,7 @@ export type GlueStackConfig<
aliases: IGlobalAliases;
globalStyle?: GlobalStyles<IGlobalAliases, IToken, IGlobalStyle>;
plugins?: Array<any>;
themes?: ThemeStyles<Tokens>;
themes?: ThemeStyles<IToken>;
components?: {
[key: string]: {
theme: Partial<GlobalStyles<IGlobalAliases, IToken, IGlobalStyle>>;
Expand Down Expand Up @@ -164,9 +170,10 @@ type PropsResolveType = {
props?: Partial<ResolverType>;
};
type PropertyResolverType = PropsResolveType & ResolverType;
export type ExtendedConfigType = {
export type ExtendedConfigType<T> = {
propertyTokenMap?: PropertyTokenMapType;
propertyResolver?: PropertyResolverType;
plugins?: T;
};

/*********************** GLOBAL STYLE TYPES ****************************************/
Expand Down Expand Up @@ -259,19 +266,23 @@ export type GlobalStyles<AliasTypes, TokenTypes, Variants> = GlobalVariantSx<

/*********************** USER THEME / SX TYPES ****************************************/

export type ITheme<Variants, P> = Partial<
export type ITheme<Variants, P, PluginType> = Partial<
//@ts-ignore
StyledThemeProps<Variants, P['style'], P>
StyledThemeProps<Variants, P['style'], P, PluginType>
>;

export type StyledThemeProps<
Variants,
GenericComponentStyles,
GenericComponentProps
GenericComponentProps,
PluginType
> = SxProps<
GenericComponentStyles,
Variants & GlobalVariants,
GenericComponentProps
GenericComponentProps,
'',
'',
PluginType
> & {
[Key in `@${IMediaQueries}`]: SxProps<
GenericComponentStyles,
Expand Down Expand Up @@ -345,7 +356,8 @@ export type SxProps<
Variants = unknown,
GenericComponentProps = unknown,
PLATFORM = '',
MediaQuery = ''
MediaQuery = '',
PluginType = []
> = Partial<
StylePropsType<GenericComponentStyles, PLATFORM> &
PassingPropsType<
Expand All @@ -355,6 +367,14 @@ export type SxProps<
MediaQuery
>
> & {
[key in keyof UnionToIntersection<
// @ts-ignore
ReturnType<PluginType[number]['inputMiddleWare']>
>]: UnionToIntersection<
// @ts-ignore
ReturnType<PluginType[number]['inputMiddleWare']>
>[key];
} & {
[Key in `_${COLORMODES}`]?: SxProps<
GenericComponentStyles,
Variants,
Expand Down

0 comments on commit 0ac5a16

Please sign in to comment.