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 #101 from gluestack/release/@dank-style/[email protected]
Browse files Browse the repository at this point in the history
  • Loading branch information
ankit-tailor authored Mar 30, 2023
2 parents fbf04b9 + d5c3977 commit 9908837
Show file tree
Hide file tree
Showing 11 changed files with 234 additions and 74 deletions.
4 changes: 4 additions & 0 deletions example/storybook/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ module.exports = function (api) {
__dirname,
'../../packages/color-mode/src'
),
['@dank-style/animation-plugin']: path.join(
__dirname,
'../../packages/animation-plugin/src'
),
},
},
]
Expand Down
2 changes: 1 addition & 1 deletion example/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
"devDependencies": {
"@babel/core": "^7.19.3",
"@dank-style/react": "0.3.8",
"@dank-style/react": "0.3.9",
"@storybook/addon-actions": "^6.5.14",
"@storybook/addon-controls": "^6.5.14",
"@storybook/addon-docs": "^6.5.15",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,20 @@ It's also recommended to set up your server-side rendering (SSR) correctly. To d

```jsx
import * as React from 'react';
// import { AppRegistry } from 'react-native';
import NextDocument, { Html, Head, Main, NextScript } from 'next/document';
import { flush } from '@dank-style/react';
import { Html, Head, Main, NextScript } from 'next/document';
import { AppRegistry } from 'react-native-web';
import { flush } from '@dank-style/react';

class Document extends NextDocument {
render() {
return (
<Html style={{ height: '100%' }}>
<Head />
<body style={{ height: '100%', overflow: 'hidden' }}>
<Main />
<NextScript />
</body>
</Html>
);
}
function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}

export const style = `
Expand All @@ -132,20 +129,19 @@ html, body, #__next {
min-height: 100%;
}`;

export async function getInitialProps({ renderPage }) {
Document.getInitialProps = async ({ renderPage }: any) => {
AppRegistry.registerComponent('Main', () => Main);
const { getStyleElement } = AppRegistry.getApplication('Main');
const page = await renderPage();

const styles = [
// eslint-disable-next-line react/jsx-key
<style dangerouslySetInnerHTML={{ __html: style }} />,
getStyleElement(),
...flush(),
];
return { ...page, styles: React.Children.toArray(styles) };
}

Document.getInitialProps = getInitialProps;
};

export default Document;
```
Expand Down
165 changes: 124 additions & 41 deletions example/storybook/src/plugins/AnimationPlugin/index.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,76 +5,84 @@ canonical: https://dank.style/
---

import { Canvas, Meta, Story } from '@storybook/addon-docs';
import { Pressable, Text } from 'react-native';
import { Pressable, Text, View } from 'react-native';
import { useEffect, useState, useRef } from 'react';
import { Motion } from '@legendapp/motion';
import { Button, AppProvider, CodePreview } from '@gluestack/design-system';
import { config } from '../../components/nb.config';
import {
createStyled,
AnimationResolver,
StyledProvider,
} from '@dank-style/react';
import { createStyled, StyledProvider } from '@dank-style/react';
import { AnimationResolver } from '@dank-style/animation-plugin';

<Meta title="plugins/Animation Plugin" />

# Animation Plugin

Dank provides a Plugin to add support for Animation props using Animation Libraries like [@legendapp/motion](https://legendapp.com/open-source/motion/), [framer-motion](https://www.framer.com/motion/), and [moti](https://moti.fyi/). We will use `@legendapp/motion` in this example.

### Installation:

```bash
# using npm

npm install @dank-style/animation-plugin

# using yarn

yarn add @dank-style/animation-plugin
```

## How to use:

First step is Plugin configuration. You can add animation props as aliases
1. Initialization of the plugin:

- The Animation plugin can be initialized by creating a new instance of the `AnimationResolver` class and passing it to the `createStyled` function as an argument. The `AnimationResolver` takes an optional `styledUtils` object that maps the styled utils object. Here's an example:

> By default plugin aliases `@legendapp/motion` props.
```jsx
const styledAnimated = createdStyled([
import { createStyled } from '@dank-style/react';
import { AnimationResolver } from '@dank-style/animation-plugin';

const styled = createStyled([
new AnimationResolver({
aliases: {
':animate': animate,
':initial': initial,
':initial': 'initial',
':animate': 'animate',
':exit': 'exit',
},
}),
]);
```

Original styled object that will be processed by input middleware
- In this example, we're creating a new instance of the AnimationResolver class and passing an object with the aliases property as an argument. The aliases object maps the aliases :initial, :animate, and :exit to their corresponding animation props.

2. Example of styled component creation:

- Once the plugin is initialized, you can use the `styled` function to create styled components with animation props. Here's an example:

```jsx
{
':animate': {
opacity: 0.5,
y: 0,
},
':initial': {
y: -50,
},
':hover': {
':animate': {
opacity: 1
}
}
}
const Box = styled(Motion.View, {
':initial': { opacity: 0 },
':animate': { opacity: 1 },
':exit': { opacity: 0 },
});
```

Final internal styled object that will be resolved styled

```jsx
styledObject = {
'props': {
animate: {
opacity: 0.5,
y: 0,
},
initial: {
y: -50,
opacity: 0,
},
},
':hover': {
props: {
animate: {
opacity: 1,
},
animate: {
opacity: 1,
},
exit: {
opacity: 0,
},
}
},
};
```
Expand All @@ -83,27 +91,28 @@ styledObject = {

<AppProvider>
<CodePreview
showArgsController={false}
showArgsController={false}
metaData={{
scope: {
createStyled,
AnimationResolver,
Provider: StyledProvider,
config,
Pressable,
Text,
Motion,
useEffect,
useState,
useRef,
Motion,
},
code:`
code: `
<StyledMotionView
variant="subtle"
states={{ hover: hover }}>
<StyledText>Hover Me!</StyledText>
</StyledMotionView>`,
transformCode:(code)=>`
transformCode: (code) => `
function App(){
const styledAnimated = createStyled([new AnimationResolver({})]);
const StyledMotionViewRef = React.useRef(styledAnimated(
Expand Down Expand Up @@ -161,8 +170,8 @@ styledObject = {
);
}
`,
}}/>

}}
/>
</AppProvider>

```jsx
Expand Down Expand Up @@ -191,6 +200,80 @@ const StyledMotionView = styledAnimated(
);
```

3. Wrapper component for exit animation:

- The Animation plugin provides a wrapper component called `AnimatePresence` from [@legendapp/motion](https://legendapp.com/open-source/motion/) that checks if any component is removed from the React tree or not so that it can help with exit animation. Here's an example:

> If you are using @legendapp/motion, you can use styled.Component, which internally uses AnimatePresence from @legendapp/motion, otherwise you should use `AnimatePresence` or something similar(which animates component on exit) from your library.
```jsx
function App() {
const [show, setShow] = useState(false);

return <styled.Component>{show && <Box />}</styled.Component>;
}
```

In this example, we're using the `styled.Component` component provided by the Animation plugin to wrap the Box component which internally uses `AnimatePresence` from [@legendapp/motion](https://legendapp.com/open-source/motion/). The AnimatePresence component checks if the Box component is removed from the React tree or not so that it can help with exit animation.

<AppProvider>
<CodePreview
showArgsController={false}
metaData={{
scope: {
createStyled,
AnimationResolver,
Provider: StyledProvider,
config,
Pressable,
Motion,
Text,
View,
},
code: `
<styled.Component>{show && <StyledBox exit={{
scale: 0.5,
opacity: 0,
}} />}</styled.Component>`,
transformCode: (code) => `
function App(){
const styled = createStyled([new AnimationResolver()]);
const StyledBox = styled(
Motion.View,
{
'w': '$20',
'h': '$20',
rounded: '$md',
'bg': '$blue500',
':initial': {
opacity: 0,
scale: 0.5,
},
':animate': {
opacity: 1,
scale: 1,
},
':exit': {
opacity: 0,
scale: 0.5,
},
},
);
const [show, setShow] = React.useState(true);
return (
<Provider config={config}>
<Pressable onPress={() => setShow(!show)} style={{backgroundColor: 'red', padding: 8, borderRadius: 4, marginBottom: 8}}>
<Text style={{color: 'white'}}>{show ? 'Unmount' : 'Mount'}</Text>
</Pressable>
${code}
</Provider>
);
}
`,
}}
/>
</AppProvider>

### Limitations:

- We are converting user styled object to internal styled object through input middleware that is heavy task and will affect performance.
Expand Down
10 changes: 7 additions & 3 deletions example/storybook/src/plugins/FontsPlugin/index.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import { AppProvider, CodePreview } from '@gluestack/design-system';

# Fonts Plugin

The font plugin is a plugin for the styled function that provides a unified approach for passing font families in your styles. It allows you to specify font families using an object with fontFamily, fontWeight, and fontStyle properties. On mobile platforms such as Expo, the plugin maps these properties to a single string font family using a mapFonts callback function. On the web, the font family object is passed through without modification.
The font plugin is a plugin for the styled function that provides a unified approach for passing font families in your styles. It allows you to specify styled object with fontFamily, fontWeight, and fontStyle properties.

## Usage:

Add the `FontResolver` plugin in your createStyled array. You can pass a mapFonts callback function to the constructor to customize the font resolution logic.
Add the `FontResolver` plugin in your createStyled function. You can pass a mapFonts callback function to the constructor to customize the font resolution logic.

```js
const styledFonts = createStyled([new FontResolver()]);
Expand All @@ -34,7 +34,11 @@ Original styled object that will be processed by mapFonts
}
```

By default, the `mapFonts` function will remove any spaces from the fontFamily property, concatenate the fontWeight property with its corresponding weight name (e.g. 800ExtraBold), and capitalize the first letter of the fontStyle property. This follows the [expo-google-fonts](https://github.com/expo/google-fonts/tree/master/font-packages/dev#readme) naming convention
The `mapFonts` function is responsible for merging font styles in a unified format, based on the specified strategy. The strategy is determined by the `DANK_STYLE_FONT_RESOLVER_STRATEGY` environment variable, which can be set to either `expo` or `web`.

If the strategy is set to `expo`, the function will follow the [expo-google-fonts](https://github.com/expo/google-fonts/tree/master/font-packages/dev#readme) naming convention by removing any spaces from the `fontFamily` property, concatenating the `fontWeight` property with its corresponding weight name (e.g. 800ExtraBold), and capitalizing the first letter of the `fontStyle` property. If the strategy is set to `web`, the function will follow a web naming convention. In either case, the `mapFonts` function will merge the font styles into a unified format that can be used by the application.

Resolved fonts object

```js
{
Expand Down
5 changes: 5 additions & 0 deletions example/storybook/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const cssInjectorPath = path.resolve(
__dirname,
'../../packages/css-injector/src'
);
const animationPluginRoot = path.resolve(
__dirname,
'../../packages/animation-plugin/src'
);
const cssifyPath = path.resolve(__dirname, '../../packages/cssify/src');

const node_modules = path.join(workspaceRoot, 'node_modules');
Expand All @@ -28,6 +32,7 @@ module.exports = async function (env, argv) {
path.resolve(colorModeRoot, 'src'),
path.resolve(cssifyPath, 'src'),
path.resolve(cssInjectorPath, 'src'),
path.resolve(animationPluginRoot, 'src'),
// path.resolve(designSystem, "src"),
],
use: 'babel-loader',
Expand Down
Loading

0 comments on commit 9908837

Please sign in to comment.