diff --git a/README.md b/README.md index 8ea241a5d..73d5e4f73 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Documentation -You can find detailed documentation for each component, including a list of props and examples, in https://gluestack.io/styledocs website. +You can find detailed documentation for each component, including a list of props and examples, in https://gluestack.io/style/docs website. ## Features diff --git a/example/storybook/.ondevice/storybook.requires.js b/example/storybook/.ondevice/storybook.requires.js index 0c8a85310..885793009 100644 --- a/example/storybook/.ondevice/storybook.requires.js +++ b/example/storybook/.ondevice/storybook.requires.js @@ -7,7 +7,8 @@ import { addArgsEnhancer, clearDecorators, } from '@storybook/react-native'; - +import { config } from '../src/components/nb.config'; +console.log(Object.keys(config)); global.STORIES = [ { titlePrefix: '', @@ -52,8 +53,8 @@ const getStories = () => { // "./src/api/AsForwarder/AsForwarder.stories.tsx": require("../src/api/AsForwarder/AsForwarder.stories.tsx"), // "./src/api/ColorModeBasedStyles/ColorMode.stories.tsx": require("../src/api/ColorModeBasedStyles/ColorMode.stories.tsx"), // "./src/api/CompoundVariants/CompoundVarinats.stories.tsx": require("../src/api/CompoundVariants/CompoundVarinats.stories.tsx"), - './src/api/createStyled/createStyled.stories.tsx': require('../src/api/createStyled/createStyled.stories.tsx'), - './src/api/DescendantsStyles/ContextBasedStyles.stories.tsx': require('../src/api/DescendantsStyles/ContextBasedStyles.stories.tsx'), + // './src/api/createStyled/createStyled.stories.tsx': require('../src/api/createStyled/createStyled.stories.tsx'), + // './src/api/DescendantsStyles/ContextBasedStyles.stories.tsx': require('../src/api/DescendantsStyles/ContextBasedStyles.stories.tsx'), // "./src/api/MultipleProvder/MultipleProvider.stories.tsx": require("../src/api/MultipleProvder/MultipleProvider.stories.tsx"), // "./src/api/PlatformBasedStyles/PlatformBasedStyles.stories.tsx": require("../src/api/PlatformBasedStyles/PlatformBasedStyles.stories.tsx"), // "./src/api/PropertyResolver/PropertyResolver.stories.tsx": require("../src/api/PropertyResolver/PropertyResolver.stories.tsx"), @@ -65,7 +66,7 @@ const getStories = () => { // "./src/api/Typescript/Typescript.stories.tsx": require("../src/api/Typescript/Typescript.stories.tsx"), // "./src/api/UtilityFunctions/UtilityFunctions.stories.tsx": require("../src/api/UtilityFunctions/UtilityFunctions.stories.tsx"), // "./src/api/Variants/BaseStyleVariantSizes.stories.tsx": require("../src/api/Variants/BaseStyleVariantSizes.stories.tsx"), - // "./src/plugins/AnimationPlugin/Animation.stories.tsx": require("../src/plugins/AnimationPlugin/Animation.stories.tsx"), + './src/plugins/AnimationPlugin/Animation.stories.tsx': require('../src/plugins/AnimationPlugin/Animation.stories.tsx'), // "./src/plugins/CSSVariables/CSSVariables.stories.tsx": require("../src/plugins/CSSVariables/CSSVariables.stories.tsx"), // "./src/plugins/FontsPlugin/FontsPlugin.stories.tsx": require("../src/plugins/FontsPlugin/FontsPlugin.stories.tsx"), }; diff --git a/example/storybook/.storybook/preview.js b/example/storybook/.storybook/preview.js index 970bbc380..15f32f0e2 100644 --- a/example/storybook/.storybook/preview.js +++ b/example/storybook/.storybook/preview.js @@ -35,7 +35,6 @@ export const parameters = { 'Overriding Styles (sx)', 'Overriding Styles (Utility Props)', 'Property Resolver', - 'createStyled()', 'Props Passing', 'Utility Functions', 'AsForwarder', diff --git a/example/storybook/babel.config.js b/example/storybook/babel.config.js index b27308285..0b330301d 100644 --- a/example/storybook/babel.config.js +++ b/example/storybook/babel.config.js @@ -5,6 +5,7 @@ module.exports = function (api) { return { presets: ['babel-preset-expo'], plugins: [ + 'react-native-reanimated/plugin', process.env.NODE_ENV !== 'production' ? [ 'module-resolver', @@ -15,14 +16,18 @@ module.exports = function (api) { __dirname, '../../packages/react/src' ), - ['@gluestack-style/animation-plugin']: path.join( + ['@gluestack-style/legend-motion-animation-driver']: path.join( __dirname, - '../../packages/animation-plugin/src' + '../../packages/animation-legend-motion-driver/src' + ), + ['@gluestack-style/moti-driver']: path.join( + __dirname, + '../../packages/animation-moti-animation-driver/src' + ), + ['@gluestack-style/animation-resolver']: path.join( + __dirname, + '../../packages/animation-resolver/src' ), - // ['@gluestack-style/animation-plugin']: path.join( - // __dirname, - // '../../packages/animation-plugin/src' - // ), // ['@dank-style/react']: path.join( // __dirname, // '../../packages/react/src' diff --git a/example/storybook/package.json b/example/storybook/package.json index 4fc488445..04fb7dd3a 100644 --- a/example/storybook/package.json +++ b/example/storybook/package.json @@ -23,7 +23,6 @@ }, "dependencies": { "@expo/html-elements": "^0.4.2", - "@gluestack-style/animation-plugin": "latest", "@gluestack-style/react": "^0.2.11-alpha.0", "@gluestack-ui/actionsheet": "^0.2.16", "@gluestack-ui/alert-dialog": "^0.1.14", @@ -53,8 +52,11 @@ "expo-status-bar": "~1.4.2", "fs": "^0.0.1-security", "lucide-react-native": "^0.236.0", + "moti": "^0.26.0", "prism-react-renderer": "^1.3.5", "react": "^18.2.0", + "react-native-gesture-handler": "^2.13.1", + "react-native-reanimated": "~2.12.0", "react-native-safe-area-context": "^4.4.1", "react-native-svg": "13.4.0", "react-native-web": "^0.19.7", @@ -95,6 +97,9 @@ "typescript": "^5.1.6" }, "peerDependencies": { + "@gluestack-style/legend-motion-animation-driver": "*", + "@gluestack-style/moti-animation-driver": "*", + "@gluestack-style/animation-resolver": "*", "react": "*", "react-dom": "*", "react-native": "*", diff --git a/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx b/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx index 3ba5d4dea..03351aa26 100644 --- a/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx +++ b/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx @@ -1,395 +1,144 @@ -import React, { - useCallback, - useEffect, - useLayoutEffect, - useMemo, - useRef, - useState, -} from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; -import { - Pressable as RNPressable, - Text as RNText, - StyleSheet, - Switch, - View, -} from 'react-native'; -import { - AsForwarder, - createStyled, - styled, - Theme, - useBreakpointValue, - useColorMode, - useStyled, - useToken, -} from '@gluestack-style/react'; +import { Pressable as RNPressable, Text as RNText, View } from 'react-native'; +import { AsForwarder, styled } from '@gluestack-style/react'; import { Wrapper } from '../../components/Wrapper'; -import { AddIcon, Box, Icon } from '@gluestack/design-system'; -// import { AddIcon } from '@gluestack/design-system'; -import { AlertCircle, Circle, Sun } from 'lucide-react-native'; - -import { AnimationResolver } from '@gluestack-style/animation-plugin'; -import { ScrollView } from 'react-native'; - -const styleshet = StyleSheet.create({ - style: { - padding: 12, - }, -}); +import { AnimatedView } from '@gluestack-style/animation-resolver'; +import { CameraIcon } from 'lucide-react-native'; -const Pressable = styled( - RNPressable, +import Link from 'next/link'; +import { Pressable } from 'react-native'; +export const BaseIcon = styled( + AsForwarder, { - bg: '$red200', - p: '$2', - props: { - variant: 'solid', + color: '$backgroundLight800', + _dark: { + color: '$backgroundDark400', }, variants: { - variant: { - solid: { - bg: '$red400', + size: { + '2xs': { + h: '$3', + w: '$3', + props: { + // @ts-ignore + size: 12, + }, + }, + 'xs': { + h: '$3.5', + w: '$3.5', + props: { + //@ts-ignore + size: 14, + }, + }, + 'sm': { + h: '$4', + w: '$4', + props: { + //@ts-ignore + size: 16, + }, + }, + 'md': { + h: '$4.5', + w: '$4.5', + props: { + //@ts-ignore + size: 18, + }, + }, + 'lg': { + h: '$5', + w: '$5', + props: { + //@ts-ignore + size: 20, + }, + }, + 'xl': { + h: '$6', + w: '$6', + props: { + //@ts-ignore + size: 24, + }, }, }, }, }, { - componentName: 'Pressable', - descendantStyle: ['_text'], - } -); - -const Pressable1 = styled( - Pressable, - { - bg: '$red200', - p: '$2', - - // 'bg': '$red600', - // 'w': 100, - // 'h': 100, - // '_light': { - // bg: '$red600', - // }, - // '@base': { - // bg: '$blue500', - // }, - // ':hover': { - // bg: '$red500', - // }, - }, - { - componentName: 'Pressable', - // descendantStyle: ['_text'], - } -); - -const Text = styled( - RNText, - {}, + componentName: 'BaseIcon', + resolveProps: ['stroke', 'fill'], + } as const, { - componentName: 'Text', - } -); - -const StyledIcon = styled( - View, - { - bg: '$amber100', - bgColor: '$amber100', - variants: { - size: { - sm: {}, - }, + propertyTokenMap: { + stroke: 'colors', + fill: 'colors', }, - // variants: { - // size: { - // sm: { - // width: 10, - // height: 10, - // // props: { - // // size: 32, - // // }, - // }, - // md: { - // // props: { - // // size: 32, - // // }, - // width: '$4', - // height: '$4', - // }, - // lg: { - // // props: { - // // size: 32, - // // }, - // width: '$6', - // height: '$6', - // }, - // }, - // }, - }, - { - componentName: 'MyIcon', } ); -const MyIcon = styled( - StyledIcon, +const StyledIcon = styled( + BaseIcon, { props: { size: 'md', + //@ts-ignore + fill: 'none', + }, + color: '$backgroundLight800', + _dark: { + //@ts-ignore + color: '$backgroundDark400', }, }, - { - componentName: 'MyNewIcon', - } + { componentName: 'Icon' } ); -// console.log( -// MyIcon.isComposedComponent, -// MyIcon.isStyledComponent, -// // MyNewIcon.isComposedComponent, -// // MyNewIcon.isStyledComponent, -// 'composed here' -// ); - -const Box1 = styled( - View, +const Text = styled( + RNText, { - // bg: '$amber400', - // h: 100, - // w: 100, - // _dark: { - // props: { - // bg: '$red500', - // }, - // }, - _text: { - color: '$red500', - }, + color: '$red500', }, { - descendantStyle: ['_text'], + componentName: 'Text', } ); - const Text1 = styled( Text, { - // _dark: { - // color: '$green500', - // }, - // variants: { - // variant: { - // sm: { - // color: '$red500', - // }, - // lg: { - // color: '$blue500', - // }, - // }, - // }, - _dark: { - color: '$black', - }, + color: '$amber300', }, - { ancestorStyle: ['_text'], componentName: 'TEXT' } + { + componentName: 'Text1', + } ); -const StyledSwitch = styled(ScrollView, {}); - +const MyLink = styled(Link, {}); export function ContextBasedStyles() { - const [state, setState] = useState(false); - return ( - - { - setState(!state); - }} - > - color mode: {state ? 'dark' : 'light'} - - - + {/* */} + {/* - - - - {/* - */} - - - {/* */} - {/* */} + - Hello - */} - {/* - */} + next link + ); } -export function ContextBasedStylesContent() { - // return ; - - const [tabName, setTabName] = useState(true); - const [state, setState] = useState(false); - - const handleTabChange = (tabName: any) => { - setTabName(tabName); - }; - - const value = useBreakpointValue({ - base: true, - sm: false, - }); - - console.log(value, 'value here'); - // const color = tabName ? '$red500' : '$green500'; - // return ( - // <> - // {/* - // - // - // */} - // {/* - // { - // handleTabChange(!tabName); - // }} - // bg="$amber400" - // h="$50" - // w="$50" - // > - // - // hello world - // - // */} - // - // ); - - // return ( - // <> - // - // - // ); - return ( - <> - { - setState(!state); - }} - style={{ - height: 50, - width: 200, - backgroundColor: 'red', - position: 'absolute', - top: 0, - left: 0, - }} - > - {state ? 'Unmount' : 'Mount'} - - {/* - Hello - */} - {/* {state && - } */} - {/* */} - {state && } - {/* */} - - ); -} - -const renderItem = (item: any) => ( - - {/* {item} */} - -); - -const renderItem2 = (item: any) => ( - - {/* {item}r */} - -); - -const MyList = React.memo(() => { - const time = React.useRef(Date.now()); - useEffect(() => { - console.log(Date.now() - time.current, '>>>'); - }, []); - const data = useMemo( - () => - Array(1) - .fill(0) - .map((_, index) => `Item ${index}`), - [] - ); - - return <>{data.map(renderItem)}; -}); export default ContextBasedStyles; diff --git a/example/storybook/src/api/ExtendComponents/ExtendComponents.stories.tsx b/example/storybook/src/api/ExtendComponents/ExtendComponents.stories.tsx new file mode 100644 index 000000000..43a2292b2 --- /dev/null +++ b/example/storybook/src/api/ExtendComponents/ExtendComponents.stories.tsx @@ -0,0 +1,10 @@ +import type { ComponentMeta } from '@storybook/react-native'; +import { ExtendComponentsExample } from './ExtendComponents'; +const MySpecificityMeta: ComponentMeta = { + title: 'api/stories/ExtendComponents', + component: ExtendComponentsExample, +}; + +export { ExtendComponentsExample as ExtendComponents } from './ExtendComponents'; + +export default MySpecificityMeta; diff --git a/example/storybook/src/api/ExtendComponents/ExtendComponents.tsx b/example/storybook/src/api/ExtendComponents/ExtendComponents.tsx new file mode 100644 index 000000000..9c99e08d8 --- /dev/null +++ b/example/storybook/src/api/ExtendComponents/ExtendComponents.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { View, Text } from 'react-native'; +import { Wrapper } from '../../components/Wrapper'; +import { Camera } from 'lucide-react-native'; +import { StyledHeading } from '../../ui-components/AsForwarder'; +import { H2 } from '@expo/html-elements'; +import { + StyledProvider, + createComponents, + styled, +} from '@gluestack-style/react'; +import { config } from '../../components/nb.config'; + +config.components = { + Box: { + theme: { + bg: '$red500', + p: '$10', + // props: { + // ':initial': { + // scale: 0.5, + // }, + // ':animate': { + // scale: 1, + // }, + // props: { + // p: '$5', + // }, + // }, + }, + }, +}; + +const Box = styled( + AnimatedView, + {}, + { + componentName: 'Box', + } +); +import Svg from 'react-native-svg'; +import { AnimatedView } from '@gluestack-style/animation-resolver'; + +export function ExtendComponentsExample() { + const [state, setState] = React.useState(false); + return ( + + + + + + ); +} + +export default ExtendComponentsExample; +// variant reserved keys +// not utility props as utility props get resolved first diff --git a/example/storybook/src/components/nb.config.ts b/example/storybook/src/components/nb.config.ts index 684875eb0..9f922adf5 100644 --- a/example/storybook/src/components/nb.config.ts +++ b/example/storybook/src/components/nb.config.ts @@ -1,5 +1,7 @@ -import { AnimationResolver } from '@gluestack-style/animation-plugin'; -import { createConfig } from '@gluestack-style/react'; +import { AnimationResolver } from '@gluestack-style/animation-resolver'; +import { MotionAnimationDriver } from '@gluestack-style/legend-motion-animation-driver'; +// import { MotiAnimationDriver } from '@gluestack-style/moti-animation-driver'; +import { createComponents, createConfig } from '@gluestack-style/react'; export const config = createConfig({ aliases: { @@ -715,6 +717,7 @@ export const config = createConfig({ // }, }, }, + plugins: [new AnimationResolver(MotionAnimationDriver)], components: { Box: { theme: { @@ -732,6 +735,16 @@ export const config = createConfig({ type ConfigType = typeof config; +// export const components = createComponents({ +// Box: { +// theme: { +// bg: '$amber400', +// h: 100, +// w: 100, +// }, +// }, +// }); + declare module '@gluestack-style/react' { interface ICustomConfig extends ConfigType {} } diff --git a/example/storybook/src/overview/API/index.stories.mdx b/example/storybook/src/overview/API/index.stories.mdx index 484fc5379..3401b0f86 100644 --- a/example/storybook/src/overview/API/index.stories.mdx +++ b/example/storybook/src/overview/API/index.stories.mdx @@ -87,7 +87,7 @@ and propertyResolver that is specific to the component. }, }, - + } ``` diff --git a/example/storybook/src/plugins/AnimationPlugin/AnimationPlugin.tsx b/example/storybook/src/plugins/AnimationPlugin/AnimationPlugin.tsx index 5e630e00e..50b6cc953 100644 --- a/example/storybook/src/plugins/AnimationPlugin/AnimationPlugin.tsx +++ b/example/storybook/src/plugins/AnimationPlugin/AnimationPlugin.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { Wrapper } from '../../components/Wrapper'; -import { Motion } from '@legendapp/motion'; -import { Pressable, View } from 'react-native'; -import { FontResolver, styled } from '@gluestack-style/react'; -import { AnimationResolver } from '@gluestack-style/animation-plugin'; +import { Pressable, View, Text } from 'react-native'; +import { styled } from '@gluestack-style/react'; +import { + AnimatedImage, + AnimatePresence, +} from '@gluestack-style/animation-resolver'; const images = [require('./1.png'), require('./2.png'), require('./3.png')]; - const Box = styled(View, {}); - const StyledMotionImage = styled( - Motion.Image, + AnimatedImage, { ':animate': { zIndex: 1, @@ -19,9 +19,7 @@ const StyledMotionImage = styled( }, }, {}, - { - plugins: [new AnimationResolver({})], - } + {} ); export function AnimationPlugin() { @@ -42,18 +40,19 @@ export function AnimationPlugin() { 'aspectRatio': 1 * 1.4, }} > - {/* @ts-ignore */} - + - {/* @ts-ignore */} - + (prev + 1) % images.length); }} > - {'‣'} + {'‣'} (prev - 1 + images.length) % images.length); }} > - {'‣'} + {'‣'} ); diff --git a/example/storybook/src/plugins/AnimationPlugin/index.stories.mdx b/example/storybook/src/plugins/AnimationPlugin/index.stories.mdx index b88938bfe..6efbe4470 100644 --- a/example/storybook/src/plugins/AnimationPlugin/index.stories.mdx +++ b/example/storybook/src/plugins/AnimationPlugin/index.stories.mdx @@ -7,11 +7,15 @@ canonical: https://gluestack.io/style import { Canvas, Meta, Story } from '@storybook/addon-docs'; import { Pressable, Text, View } from 'react-native'; import { useEffect, useState, useRef } from 'react'; -import { Motion, AnimatePresence } from '@legendapp/motion'; +import { Motion } from '@legendapp/motion'; import { Button, AppProvider, CodePreview } from '@gluestack/design-system'; import { config } from '../../components/nb.config'; -import { createStyled, StyledProvider } from '@gluestack-style/react'; -import { AnimationResolver } from '@gluestack-style/animation-plugin'; +import { StyledProvider, styled } from '@gluestack-style/react'; +import { + AnimatedImage, + AnimatedView, + AnimatePresence, +} from '@gluestack-style/animation-resolver'; @@ -24,34 +28,29 @@ gluestack-style offers a plugin that supports animation properties, utilizing an ```bash # using npm -npm install @gluestack-style/animation-plugin +npm install @gluestack-style/animation-resolver # using yarn -yarn add @gluestack-style/animation-plugin +yarn add @gluestack-style/animation-resolver ``` ## How to use: ### Initialization of the plugin: -- You can initialize the Animation plugin by creating a new instance of the AnimationResolver class and providing it as an argument to the createStyled function. The `AnimationResolver` takes an optional `styledUtils` object that maps the styled utils object. Here's an example: +- You can initialize the Animation plugin by creating a new instance of the AnimationResolver class and pass it inside config. The `AnimationResolver` takes an optional `styledUtils` object that maps the styled utils object. Here's an example: > By default, the plugin aliases `@legendapp/motion` properties. ```jsx -import { createStyled } from '@gluestack-style/react'; -import { AnimationResolver } from '@gluestack-style/animation-plugin'; +import { AnimationResolver } from '@gluestack-style/animation-resolver'; -const styled = createStyled([ - new AnimationResolver({ - aliases: { - ':initial': 'initial', - ':animate': 'animate', - ':exit': 'exit', - }, - }), -]); +export const config = { + aliases: {}, + tokens: {}, + plugins: [new AnimationResolver()], +}; ``` - In this example, we are creating a new instance of the AnimationResolver class, 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. @@ -61,7 +60,9 @@ const styled = createStyled([ - Once the plugin is initialized, you can use the `styled` function to create styled components with animation props. Here's an example: ```jsx -const Box = styled(Motion.View, { +import { AnimatedView } from '@gluestack-style/animation-resolver'; + +const Box = styled(AnimatedView, { ':initial': { opacity: 0 }, ':animate': { opacity: 1 }, ':exit': { opacity: 0 }, @@ -87,264 +88,14 @@ styledObject = { }; ``` -### Example: +## Exit animation: - - - Hover Me! -`, - transformCode: (code) => ` - function App(){ - const styled = createStyled([new AnimationResolver({})]); - const StyledMotionViewRef = React.useRef(styled( - Motion.View, - { - px: '$3.5', - py: '$2.5', - 'bg': '$blue600', - alignItems: 'center', - justifyContent: 'center', - rounded: '$md', - cursor: 'pointer', - ':animate': { - scale: 1, - }, - ':hover': { - ':animate': { - scale: 1.2 - }, - }, - _text: { - fontSize: '$md', - lineHeight: '$md', - color: '$white', - } - }, - { - descendantStyle: ['_text'], - }, - )); - const StyledMotionView = StyledMotionViewRef.current; - const StyledText = styled( - Text, - {}, - { - ancestorStyle: ['_text'], - }, - ); - const [ hover, setHover ] = React.useState(false); - const ref = React.useRef(); - React.useEffect(() => { - if (ref && ref.current) { - ref.current.addEventListener('mouseover', () => { - setHover(true); - }); - ref.current.addEventListener('mouseleave', () => { - setHover(false); - }); - } - }, []); - return ( - -
- ${code} -
-
- ); - } - `, - }} - /> -
+- The Animation plugin provides a `AnimatePresence` component. Internally, it utilizes `AnimatePresence` from activated animation driver to check if any component is removed from the React tree, aiding in exit animations. Here's an example: We used the styled component below to create the above example: ```jsx -const styled = createStyled([new AnimationResolver({})]); -const StyledMotionView = styled( - Motion.View, - { - 'px': '$3.5', - 'py': '$2.5', - 'bg': '$blue600', - 'alignItems': 'center', - 'justifyContent': 'center', - 'rounded': '$md', - 'cursor': 'pointer', - ':animate': { - scale: 1, - opacity: 0.9, - }, - ':hover': { - ':animate': { - scale: 1.2, - }, - }, - '_text': { - fontSize: '$md', - lineHeight: '$md', - color: '$white', - }, - }, - { - descendantStyle: ['_text'], - } -); -``` - -## Wrapper component for exit animation: - -- The Animation plugin provides a wrapper component. Internally, it utilizes AnimatePresence from [@legendapp/motion](https://legendapp.com/open-source/motion/) to check if any component is removed from the React tree, aiding in exit animations. Here's an example: - - - - - `, - transformCode: (code) => ` - function App(){ - const styledRef = React.useRef(createStyled([new AnimationResolver()])); - const styled = styledRef.current; -const images = ['https://i.imgur.com/v6VFkPR.jpeg', 'https://i.imgur.com/5p1B7TT.jpeg', 'https://i.imgur.com/kvwOXOl.jpeg']; -const BoxRef = React.useRef(styled(View, {})); -const Box = BoxRef.current; -const StyledMotionImageRef = React.useRef(styled(Motion.Image, { - ':animate': { - zIndex: 1, - x: 0, - opacity: 1, - }, -})); -const StyledMotionImage = StyledMotionImageRef.current; - const [imageIndex, setImageIndex] = React.useState(0); - const [xPosition, setXPosition] = React.useState(0); - return ( - - - ${code} - - { - setXPosition(1000); - setImageIndex((prev) => (prev + 1) % images.length); - }} - > - {'‣'} - - { - setXPosition(-1000); - setImageIndex((prev) => (prev - 1 + images.length) % images.length); - }} - > - {'‣'} - - - ); - } - `, - }} - /> - - -We used the styled component below to create the above example: - -```jsx -const styled = createStyled([new AnimationResolver()]); -const StyledMotionImageRef = styled(Motion.Image, { +const StyledMotionImage = styled(AnimatedImage, { ':animate': { zIndex: 1, x: 0, @@ -353,10 +104,4 @@ const StyledMotionImageRef = styled(Motion.Image, { }); ``` -In this example, we're using the styled.Component, provided by the Animation plugin, to wrap the Box component. Internally, it uses AnimatePresence from @legendapp/motion(https://legendapp.com/open-source/motion/). - -> If you're using @legendapp/motion, you can use styled.Component, which internally utilizes AnimatePresence from @legendapp/motion. Otherwise, you should use AnimatePresence or a similar function (that animates components on exit) from your library. - -## Limitations: - -- Typings are not yet supported for animation props +In this example, we're using the `AnimatePresence`, provided by the animation resolver, to wrap the Box component. Internally, it uses `AnimatePresence` from activated animation driver. diff --git a/example/storybook/src/plugins/FontsPlugin/index.stories.mdx b/example/storybook/src/plugins/FontsPlugin/index.stories.mdx index a4d56aa37..aeb8dc30b 100644 --- a/example/storybook/src/plugins/FontsPlugin/index.stories.mdx +++ b/example/storybook/src/plugins/FontsPlugin/index.stories.mdx @@ -6,11 +6,7 @@ canonical: https://gluestack.io/style import { Canvas, Meta, Story } from '@storybook/addon-docs'; import { Text } from 'react-native'; -import { - StyledProvider, - createStyled, - FontResolver, -} from '@gluestack-style/react'; +import { StyledProvider, styled, FontResolver } from '@gluestack-style/react'; import { config } from '../../components/nb.config'; import { AppProvider, CodePreview } from '@gluestack/design-system'; @@ -22,10 +18,16 @@ The font plugin, a utility for the styled function, provides a unified way to pa ## Usage: -Include the FontResolver plugin in your createStyled function. To customize font resolution, pass a mapFonts callback function to the constructor. +Include the `FontResolver` plugin in your config. To customize font resolution, pass a mapFonts callback function to the constructor. ```js -const styledFonts = createStyled([new FontResolver()]); +import { FontResolver } from '@gluetsack-style/react'; + +export const config = { + aliases: {}, + tokens: {}, + plugins: [new FontResolver()], +}; ``` Below is an example of an original styled object that will be processed by mapFonts @@ -57,16 +59,15 @@ Below is an example of a resolved fonts object showArgsController={false} metaData={{ scope: { - createStyled, FontResolver, Text, Provider: StyledProvider, config, + styled, }, code: ` function App () { - const styledFonts = createStyled([new FontResolver({})]); - const StyledText = styledFonts(Text, { + const StyledText = styled(Text, { fontFamily: 'Nunito Sans', fontWeight: 800, fontStyle: 'italic', @@ -93,11 +94,10 @@ Below is an example of a resolved fonts object ## mapFonts: -To use a different naming convention for your fonts, provide a custom mapFonts function to the font plugin constructor. +To use a different naming convention for your fonts, provide a custom mapFonts function to the font plugin constructor and pass it inside the config. ```js -const styledFonts = createStyled([ - new FontResolver({ +const CustomFontResolver = new FontResolver({ mapFonts: (style) => { if (Platform.OS !== 'web') { style.fontFamily = @@ -106,6 +106,11 @@ const styledFonts = createStyled([ style.fontStyle = undefined; } }, - }), -]); +}), + +export const config = { + aliases: {}, + tokens: {}, + plugins: [CustomFontResolver], +}; ``` diff --git a/example/storybook/src/plugins/Introduction/index.stories.mdx b/example/storybook/src/plugins/Introduction/index.stories.mdx index 83eca9f36..e40a53159 100644 --- a/example/storybook/src/plugins/Introduction/index.stories.mdx +++ b/example/storybook/src/plugins/Introduction/index.stories.mdx @@ -41,8 +41,14 @@ class IStyled { 4. `componentMiddleWare`: This optional method allows plugins to access the React component being styled. This could be useful for plugins that need to perform more complex operations based on the component, such as adding or modifying props, or interacting with component lifecycle methods. -5. `wrapperComponent`: At times, you might need to introduce a new component to handle specific functionalities when rendering a component tree. In this case, you want your plugin to be able to introduce the new component and modify props/children as well. +### Usage: -### createStyled +You can use plugins inside your config: -The createStyled function accepts an array of plugins and returns an extended styled function that incorporates the added functionalities of those plugins. The extended styled function can be used to create styled components, just like the original styled function. +``` +export const config = { + aliases: {}, + tokens: {}, + plugins: [new MyPlugin()] +} +``` diff --git a/example/storybook/tsconfig.json b/example/storybook/tsconfig.json index 8ad2be9db..6b68e3568 100644 --- a/example/storybook/tsconfig.json +++ b/example/storybook/tsconfig.json @@ -4,8 +4,14 @@ "baseUrl": ".", "paths": { "@gluestack-style/react": ["../../packages/react/src"], - "@gluestack-style/animation-plugin": [ - "../../packages/animation-plugin/src" + "@gluestack-style/legend-motion-animation-driver": [ + "../../packages/animation-legend-motion-driver/src" + ], + "@gluestack-style/moti-animation-driver": [ + "../../packages/animation-moti-driver/src" + ], + "@gluestack-style/animation-resolver": [ + "../../packages/animation-resolver/src" ], "react-native": ["./node_modules/react-native-web"] }, diff --git a/example/ui-examples-babel/App.tsx b/example/ui-examples-babel/App.tsx index 12ac30f41..d1b24831a 100644 --- a/example/ui-examples-babel/App.tsx +++ b/example/ui-examples-babel/App.tsx @@ -1,29 +1,30 @@ +// @ts-nocheck import React, { - useCallback, - useEffect, - useLayoutEffect, - useMemo, - useRef, + // useCallback, + // useEffect, + // useLayoutEffect, + // useMemo, + // useRef, useState, } from 'react'; import { - Pressable as RNPressable, - Text as RNText, - StyleSheet, + // Pressable as RNPressable, + // Text as RNText, + // StyleSheet, View, Pressable, Text, } from 'react-native'; import { - AsForwarder, + // AsForwarder, styled, - Theme, + // Theme, StyledProvider, } from '@gluestack-style/react'; import { config } from './gluestack-ui.config'; -import { createMotionAnimatedComponent, Motion } from '@legendapp/motion'; -import { AnimationResolver } from '@gluestack-style/animation-plugin'; +// import { createMotionAnimatedComponent, Motion } from '@legendapp/motion'; +// import { AnimationResolver } from '@gluestack-style/animation-plugin'; const Box = styled(View, { bg: '$yellow500', diff --git a/example/ui-examples/babel.config.js b/example/ui-examples/babel.config.js index 4c37cddd7..4a8688a1e 100644 --- a/example/ui-examples/babel.config.js +++ b/example/ui-examples/babel.config.js @@ -6,18 +6,18 @@ module.exports = function (api) { return { presets: ['babel-preset-expo'], plugins: [ - [ - myBabel, - { - configPath: path.join(__dirname, './gluestack-ui.config.ts'), - configThemePath: ['theme'], - styled: [ - '@gluestack-style/react', - path.resolve(__dirname, './gluestack-ui-components/core/styled'), - ], - components: ['@gluesatck-ui/themed'], - }, - ], + // [ + // myBabel, + // { + // configPath: path.join(__dirname, './gluestack-ui.config.ts'), + // configThemePath: ['theme'], + // styled: [ + // '@gluestack-style/react', + // path.join(__dirname, '../../packages/react/src'), + // ], + // components: ['@gluesatck-ui/themed'], + // }, + // ], [ 'module-resolver', { @@ -27,6 +27,18 @@ module.exports = function (api) { __dirname, '../../packages/react/src' ), + ['@gluestack-style/animation-resolver']: path.join( + __dirname, + '../../packages/animation-resolver/src' + ), + ['@gluestack-style/legend-motion-animation-driver']: path.join( + __dirname, + '../../packages/animation-legend-motion-driver/src' + ), + ['@gluestack-ui/themed']: path.join( + __dirname, + '../../../gluestack-ui/packages/themed' + ), // ['@gluestack-style/animation-plugin']: path.join( // __dirname, // '../../packages/animation-plugin/src' diff --git a/example/ui-examples/gluestack-ui.config.ts b/example/ui-examples/gluestack-ui.config.ts index 8b7a6c1c6..598bf9a24 100644 --- a/example/ui-examples/gluestack-ui.config.ts +++ b/example/ui-examples/gluestack-ui.config.ts @@ -1,4 +1,6 @@ -import { createConfig } from '@gluestack-style/react'; +import { MotionAnimationDriver } from '@gluestack-style/legend-motion-animation-driver'; +import { AnimationResolver } from '@gluestack-style/animation-resolver'; +import { createComponents, createConfig } from '@gluestack-style/react'; export const config = { componentPath: '/components', theme: createConfig({ @@ -617,132 +619,33 @@ export const config = { 100: 1, }, } as const, - globalStyle: { - variants: { - hardShadow: { - '1': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: -2, - height: 2, - }, - shadowRadius: 8, - shadowOpacity: 0.5, - elevation: 10, - }, - '2': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 0, - height: 3, - }, - shadowRadius: 8, - shadowOpacity: 0.5, - elevation: 10, - }, - '3': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 2, - height: 2, - }, - shadowRadius: 8, - shadowOpacity: 0.5, - elevation: 10, - }, - '4': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 0, - height: -3, - }, - shadowRadius: 8, - shadowOpacity: 0.5, - elevation: 10, - }, - }, - softShadow: { - '1': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 0, - height: 0, - }, - shadowRadius: 10, - shadowOpacity: 0.1, - _android: { - shadowColor: '$backgroundLight500', - elevation: 5, - shadowOpacity: 0.05, - }, - }, - '2': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 0, - height: 0, - }, - shadowRadius: 20, - elevation: 3, - shadowOpacity: 0.1, - _android: { - shadowColor: '$backgroundLight500', - elevation: 10, - shadowOpacity: 0.1, - }, - }, - '3': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 0, - height: 0, - }, - shadowRadius: 30, - shadowOpacity: 0.1, - elevation: 4, - _android: { - shadowColor: '$backgroundLight500', - elevation: 15, - shadowOpacity: 0.15, - }, - }, - '4': { - shadowColor: '$backgroundLight900', - shadowOffset: { - width: 0, - height: 0, - }, - shadowRadius: 40, - shadowOpacity: 0.1, - elevation: 10, - _android: { - shadowColor: '$backgroundLight500', - elevation: 20, - shadowOpacity: 0.2, - }, - }, - }, + plugins: [new AnimationResolver(MotionAnimationDriver)], + }), +} as const; + +const components = createComponents({ + MyBox: { + theme: { + 'bg': '$pink500', + ':initial': { + scale: 0.5, + bg: '$amber500', }, - }, - themes: { - x: { - colors: { - $primary100: '$colors$yellow500', - $primary500: '$colors$green500', - $amber50: '#000000', - }, + ':animate': { + scale: 1, + bg: '$pink500', }, - y: { - colors: { - $primary100: '$colors$blue500', - $primary500: '$colors$green500', - $amber50: '#FFFFFF', - }, + ':transition': { + type: 'timing', + duration: 1500, }, }, - }), -} as const; + }, +}); + type Config = typeof config.theme; +type Components = typeof components; declare module '@gluestack-style/react' { interface ICustomConfig extends Config {} + interface ICustomComponents extends Components {} } diff --git a/example/ui-examples/webpack.config.js b/example/ui-examples/webpack.config.js index 61343d616..9bfb3d0ec 100644 --- a/example/ui-examples/webpack.config.js +++ b/example/ui-examples/webpack.config.js @@ -14,7 +14,19 @@ const animationPluginRoot = path.resolve( __dirname, '../../packages/animation-plugin/src' ); +const animationResolverRoot = path.resolve( + __dirname, + '../../packages/animation-resolver/src' +); +const legendMotinDriverRoot = path.resolve( + __dirname, + '../../packages/animation-legend-motion-driver/src' +); const node_modules = path.join(__dirname, '../../node_modules'); +const gluestackThemed = path.join( + __dirname, + '../../../gluestack-ui/packages/themed' +); // const designSystem = path.resolve(__dirname, "../../../glustack-design-system"); module.exports = async function (env, argv) { const config = await createExpoWebpackConfigAsync(env, argv); @@ -24,6 +36,9 @@ module.exports = async function (env, argv) { include: [ path.resolve(styledRoot), path.resolve(animationPluginRoot), + path.resolve(animationResolverRoot), + path.resolve(legendMotinDriverRoot), + path.resolve(gluestackThemed), // path.resolve(designSystem, "src"), ], use: 'babel-loader', diff --git a/example/ui-examples/yarn.lock b/example/ui-examples/yarn.lock index a75d3c762..dd07cd98f 100644 --- a/example/ui-examples/yarn.lock +++ b/example/ui-examples/yarn.lock @@ -1669,6 +1669,13 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@gluestack-style/animation-plugin@^0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@gluestack-style/animation-plugin/-/animation-plugin-0.1.12.tgz#887b57097397817c31fef25c8c53af381c11633e" + integrity sha512-lkj8iY5JBnhroUkP5gWE1zEpocb5GAK/G9SxL8DdWYQrsWOFpXr/mF/K67Dbxiv/n4B9BVff7sNTAddju+4UAw== + dependencies: + "@legendapp/motion" "^2.2.0" + "@gluestack-style/animation-plugin@latest": version "0.1.7" resolved "https://registry.yarnpkg.com/@gluestack-style/animation-plugin/-/animation-plugin-0.1.7.tgz#c9feae42684a48f2b5ece932681837d4b3ce7104" @@ -1676,6 +1683,11 @@ dependencies: "@legendapp/motion" "^2.2.0" +"@gluestack-style/animation-resolver@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@gluestack-style/animation-resolver/-/animation-resolver-0.0.1.tgz#ea3831a076ce5dde794bf4c132185578ef114d04" + integrity sha512-vqcglbcLTCdzvtn6lCKMGc35pXpxpxtCu3SFSt8FSPqfFU8aGDmmAu267dp8XeuH/BHmvcpqLUwSazt4S5y2QA== + "@gluestack-style/babel-plugin-styled-resolver@latest": version "0.2.0" resolved "https://registry.yarnpkg.com/@gluestack-style/babel-plugin-styled-resolver/-/babel-plugin-styled-resolver-0.2.0.tgz#b040c6943d52cf086bc64ec89aed8e984c0ebd8b" @@ -1689,6 +1701,11 @@ "@babel/traverse" "^7.20.5" lodash.merge "^4.6.2" +"@gluestack-style/legend-motion-animation-driver@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@gluestack-style/legend-motion-animation-driver/-/legend-motion-animation-driver-0.0.1.tgz#474692877525f274e81f222d93f4c2af3a4d42a9" + integrity sha512-uASI3nENOd/zqnxzW66Ipkm3rjdapEIhs+TLgRAAazXdZxElImRtWvl1cuOiX/sn49QojlVefrd26uJVpVngZw== + "@gluestack-style/react@0.1.31": version "0.1.31" resolved "https://registry.yarnpkg.com/@gluestack-style/react/-/react-0.1.31.tgz#07e6740d448a49fa0133b6d94dc6239509f6b2df" @@ -1697,6 +1714,19 @@ inline-style-prefixer "^6.0.1" normalize-css-color "^1.0.2" +"@gluestack-ui/actionsheet@^0.2.20": + version "0.2.24" + resolved "https://registry.yarnpkg.com/@gluestack-ui/actionsheet/-/actionsheet-0.2.24.tgz#4718b0452d1268a01a23970717f5219c871c76ad" + integrity sha512-UJdebV6kxnEPDYUsCY4hh7lTdB7mwYs73o7eK6iHT4nHGUZXPTUOjZg8dea3z6L8IRTRwi8gMDRB9ciKWKY15A== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/transitions" "^0.1.8" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/dialog" "0.1.1" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@gluestack-ui/actionsheet@latest": version "0.2.16" resolved "https://registry.yarnpkg.com/@gluestack-ui/actionsheet/-/actionsheet-0.2.16.tgz#052a733966c517450a3cd6f832932ccf77924867" @@ -1710,6 +1740,18 @@ "@react-native-aria/focus" "^0.2.8" "@react-native-aria/interactions" "^0.2.10" +"@gluestack-ui/alert-dialog@^0.1.16": + version "0.1.17" + resolved "https://registry.yarnpkg.com/@gluestack-ui/alert-dialog/-/alert-dialog-0.1.17.tgz#6814e21e43bdb7eff6f70b13a1559901e2abda1a" + integrity sha512-VJ8DHGd36XwqJrEWSa0zZUBZ54VirfGEhpqJN5u5FL3HPDc65FRB7oqy5CKGuJHfcTvrAEibkubAqSNb2m8y2Q== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/dialog" "^0.1.1" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@gluestack-ui/alert-dialog@latest": version "0.1.14" resolved "https://registry.yarnpkg.com/@gluestack-ui/alert-dialog/-/alert-dialog-0.1.14.tgz#a494d17f68ce351dbd97c2dbd511562c506e1340" @@ -1722,11 +1764,18 @@ "@react-native-aria/focus" "^0.2.8" "@react-native-aria/interactions" "^0.2.10" -"@gluestack-ui/alert@latest": +"@gluestack-ui/alert@^0.1.8", "@gluestack-ui/alert@latest": version "0.1.8" resolved "https://registry.yarnpkg.com/@gluestack-ui/alert/-/alert-0.1.8.tgz#f9d6b6c7a2fcdc03d02edb02c11cc4c4a18fa894" integrity sha512-zDUdaAUgILeWBJhF/Ub6np35u8U0T79xsLKZl22CmH17bUHuIu1cXaiqJhGnofV/YwRv6xDIPaOXwuhaK5IoAg== +"@gluestack-ui/avatar@^0.1.10": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@gluestack-ui/avatar/-/avatar-0.1.10.tgz#536c92ebb9f263cbb8ac4f16289497975715143d" + integrity sha512-15Ed6itvI7bT8VCA5mLbQ0q9v1I7u/enK5BcQg3qKN6IVbWY6MIeT7/S7s2wvKbkNEjdN/iQWUweKPXRtZ7gEw== + dependencies: + "@gluestack-ui/utils" "^0.1.5" + "@gluestack-ui/avatar@latest": version "0.1.9" resolved "https://registry.yarnpkg.com/@gluestack-ui/avatar/-/avatar-0.1.9.tgz#cc47f6f431df576dfd37a815c71a64cdcc35c136" @@ -1734,6 +1783,15 @@ dependencies: "@gluestack-ui/utils" "^0.1.5" +"@gluestack-ui/button@^0.1.25": + version "0.1.26" + resolved "https://registry.yarnpkg.com/@gluestack-ui/button/-/button-0.1.26.tgz#1f66707e18f75524d47581298896bc0a3d9f41dd" + integrity sha512-TIZkqpTJwEn87QqmrimGKXaGZvbDhJxxRBDYq3UZlLG2j95RZ0bLwO1bLEIcE8KXJc6sGUWEvLj/4efGhijyXw== + dependencies: + "@gluestack-ui/utils" "0.1.9" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@gluestack-ui/button@latest": version "0.1.23" resolved "https://registry.yarnpkg.com/@gluestack-ui/button/-/button-0.1.23.tgz#216ed04c2d8b2bd013eff5713ca84a81ffc64140" @@ -1743,7 +1801,7 @@ "@react-native-aria/focus" "^0.2.8" "@react-native-aria/interactions" "^0.2.10" -"@gluestack-ui/checkbox@latest": +"@gluestack-ui/checkbox@^0.1.17", "@gluestack-ui/checkbox@latest": version "0.1.17" resolved "https://registry.yarnpkg.com/@gluestack-ui/checkbox/-/checkbox-0.1.17.tgz#4ebadec4b428d3d65b8983a6d4547bdae7a5f3ee" integrity sha512-6MpJgG306jKp3iip+EgkXcwYxqVkxuE+XW75+8TfOE3ZI3p0JZCuGNRSKaAOJDmwxPVPO40vm1GFPrREJvoi4g== @@ -1756,11 +1814,20 @@ "@react-native-aria/interactions" "^0.2.10" "@react-stately/checkbox" "^3.4.2" -"@gluestack-ui/divider@latest": +"@gluestack-ui/divider@^0.1.5", "@gluestack-ui/divider@latest": version "0.1.5" resolved "https://registry.yarnpkg.com/@gluestack-ui/divider/-/divider-0.1.5.tgz#3b68375e5620b2641b07465f599b2ec2259bae83" integrity sha512-5x6soIXugWyMhhufpcw54hNoGoZWrEEOb8Y/5caAGNV2YVsLACenztdkmedi5sFDfRidd407fIxjQ9zElChoCQ== +"@gluestack-ui/fab@^0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@gluestack-ui/fab/-/fab-0.1.12.tgz#bd98b74df213cc23721a05b5868628b8ddb77d16" + integrity sha512-82vyqL1DKxmvuAT+CLCJ2jn/7/HViLtFEsnaadQfHK28VNGvLudUPtN2tq8sQu5Hom4iGjkfQHcoxRQgPwqJLg== + dependencies: + "@gluestack-ui/utils" "^0.1.9" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@gluestack-ui/fab@latest": version "0.1.11" resolved "https://registry.yarnpkg.com/@gluestack-ui/fab/-/fab-0.1.11.tgz#2e7bb95397865ecdc5a087f3249639c341108aee" @@ -1787,6 +1854,13 @@ "@react-native-aria/focus" "^0.2.7" react-native-svg "13.4.0" +"@gluestack-ui/hstack@^0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@gluestack-ui/hstack/-/hstack-0.1.11.tgz#9274f33991a98062ce23b2d6f84c44b1a59676b1" + integrity sha512-Oaqopb/idtO4qw64GbIt0Gr7otJMmG0S+YFBhYWuilPNA6ugjmnnFw5JrN+uxMg1dZOwRAKUTFCyNeiJZgKW9w== + dependencies: + "@gluestack-ui/utils" "^0.1.5" + "@gluestack-ui/hstack@latest": version "0.1.8" resolved "https://registry.yarnpkg.com/@gluestack-ui/hstack/-/hstack-0.1.8.tgz#c705d1c5b821883c6502d0b3d8c9ca78600979be" @@ -1794,6 +1868,15 @@ dependencies: "@gluestack-ui/utils" "^0.1.6" +"@gluestack-ui/icon@^0.1.9": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@gluestack-ui/icon/-/icon-0.1.11.tgz#f8e44b9be532b362a0b27bfa3d0641726dc053a9" + integrity sha512-D1/Irtjv7fNbqejmujc86fWJu/s9jo5S+97XSpDAiv4ATQbJEx386UVMXOTFc90Umrgqf0p9KC939cqDJw0+TQ== + dependencies: + "@gluestack-ui/provider" "^0.1.6" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/focus" "^0.2.7" + "@gluestack-ui/icon@latest": version "0.1.6" resolved "https://registry.yarnpkg.com/@gluestack-ui/icon/-/icon-0.1.6.tgz#f823f9e345989abdb89f50cd3af456300aadd679" @@ -1804,6 +1887,25 @@ "@react-native-aria/focus" "^0.2.7" react-native-svg "13.4.0" +"@gluestack-ui/image@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@gluestack-ui/image/-/image-0.1.1.tgz#cec890a4db95bb0cb5c50b6bf03f3bd9f4bfbbeb" + integrity sha512-nxcbNs2uDB7SKsMlMLOifxON4Ifxj8Uy7LKBuGeMAvUk2zRLHkU7Yhb4g/q7gOrIZ+cYRuXLtNbICw+ZQo1v4A== + dependencies: + "@gluestack-ui/utils" "0.1.9" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + +"@gluestack-ui/input@^0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@gluestack-ui/input/-/input-0.1.16.tgz#cfc52fddbe8a98c917d210c88e70c3ba59d54698" + integrity sha512-A5TK5Yu6JAAQ+9Obb16l4QqwPRz55xXiXftCyHohz0B/GdTmHPnnSbTxbPGtOPCCAlebPcg8PAr6BYV0qY7emA== + dependencies: + "@gluestack-ui/form-control" "^0.1.10" + "@gluestack-ui/utils" "^0.1.9" + "@react-native-aria/focus" "^0.2.7" + "@react-native-aria/interactions" "^0.2.8" + "@gluestack-ui/input@latest": version "0.1.10" resolved "https://registry.yarnpkg.com/@gluestack-ui/input/-/input-0.1.10.tgz#10b40c633b43fdd45cae69a7693dacdb15f44fd3" @@ -1815,7 +1917,7 @@ "@react-native-aria/interactions" "^0.2.8" react-native-svg "13.4.0" -"@gluestack-ui/link@latest": +"@gluestack-ui/link@^0.1.10", "@gluestack-ui/link@latest": version "0.1.10" resolved "https://registry.yarnpkg.com/@gluestack-ui/link/-/link-0.1.10.tgz#5a01ad0d2cf98c312f3eb1f2b04cf5e86a21ce64" integrity sha512-VJnpsyHoZI6ADnISspYBsw2jTV1ZksUIuHafhBeARvfryBuK3pgnRAlJzXr96LXh0FUOEFR3QbmVA6eDEtUh7Q== @@ -1824,6 +1926,21 @@ "@react-native-aria/focus" "^0.2.8" "@react-native-aria/interactions" "^0.2.10" +"@gluestack-ui/menu@^0.2.19": + version "0.2.19" + resolved "https://registry.yarnpkg.com/@gluestack-ui/menu/-/menu-0.2.19.tgz#9975412e2f6973ecdb9d6532015ecaecb7017f0f" + integrity sha512-g2QBzQJlx2l9bmbZ5ayDLUJY90zutEGQ02PLEjanlILAR8RO2fksiWsUxhqTJoZmfba00Ua2dHysGSZKVTuLXQ== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@react-native-aria/menu" "^0.2.7" + "@react-native-aria/overlays" "0.3.7" + "@react-stately/utils" "^3.6.0" + react-stately "^3.21.0" + "@gluestack-ui/menu@latest": version "0.2.15" resolved "https://registry.yarnpkg.com/@gluestack-ui/menu/-/menu-0.2.15.tgz#d94f2962952e8e683106643840dc1e6094ba5ca8" @@ -1839,6 +1956,19 @@ "@react-stately/utils" "^3.6.0" react-stately "^3.21.0" +"@gluestack-ui/modal@^0.1.20": + version "0.1.21" + resolved "https://registry.yarnpkg.com/@gluestack-ui/modal/-/modal-0.1.21.tgz#8c32d77b49ee183ff9b6dfc324637e56eebfebfb" + integrity sha512-ar0UjCwLdeCaLsrCZhbu1Ujw9b4ZK2yR9FXFP1QrNqJIBiW7EOcLdIspl/N9j1k8Y1Skx+BIa79+4LA68qMs4Q== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/dialog" "^0.1.1" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@react-native-aria/overlays" "0.3.7" + "@gluestack-ui/modal@latest": version "0.1.18" resolved "https://registry.yarnpkg.com/@gluestack-ui/modal/-/modal-0.1.18.tgz#3df7210e7133bd405fc0d3f7791a9a4ce3f951b5" @@ -1861,6 +1991,19 @@ "@react-native-aria/interactions" "^0.2.10" "@react-native-aria/overlays" "^0.3.7" +"@gluestack-ui/popover@^0.1.21": + version "0.1.22" + resolved "https://registry.yarnpkg.com/@gluestack-ui/popover/-/popover-0.1.22.tgz#cf564d4c2148140c82a108a3e204704e2b575579" + integrity sha512-sTh2q9g4IgN/r63Pptsfe1h5FqEWRqxc53C9In6WSAQglxPi9ova3zFxEMsQXCIyH9HMmoUdx2KgzDnJXj2lcA== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/dialog" "^0.1.1" + "@react-native-aria/focus" "^0.2.8" + "@react-native-aria/interactions" "^0.2.10" + "@react-native-aria/overlays" "0.3.7" + "@gluestack-ui/popover@latest": version "0.1.19" resolved "https://registry.yarnpkg.com/@gluestack-ui/popover/-/popover-0.1.19.tgz#3da94f64a15e616e93bf630062c551e128efda41" @@ -1874,7 +2017,7 @@ "@react-native-aria/interactions" "^0.2.10" "@react-native-aria/overlays" "0.3.7" -"@gluestack-ui/pressable@latest": +"@gluestack-ui/pressable@^0.1.9", "@gluestack-ui/pressable@latest": version "0.1.9" resolved "https://registry.yarnpkg.com/@gluestack-ui/pressable/-/pressable-0.1.9.tgz#f9333e51202543bcfde214bba5607ca9b233a26f" integrity sha512-hWWJ+7z0g/P2nbxDr60JBnHIA676oTg7EG1FfEgd25gvyWzVJ+JjObhrxHb4V4ILK7RkaQeB1K+esAl2bSBytA== @@ -1883,13 +2026,22 @@ "@react-native-aria/focus" "^0.2.8" "@react-native-aria/interactions" "^0.2.10" -"@gluestack-ui/progress@latest": +"@gluestack-ui/progress@^0.1.7", "@gluestack-ui/progress@latest": version "0.1.7" resolved "https://registry.yarnpkg.com/@gluestack-ui/progress/-/progress-0.1.7.tgz#ef8ba9b436d055346ff773051a350a6a88ced912" integrity sha512-wV7hsdugq1PRrlNbaAg9I4WsCUC4qOZ+tpe71aNIQbSP0jtJZQBTjyynqauGnWHjqq7ECDRg+26aWdV97/3SFQ== dependencies: "@gluestack-ui/utils" "^0.1.5" +"@gluestack-ui/provider@0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@gluestack-ui/provider/-/provider-0.1.9.tgz#9956de72f462633671c57e3d16e575b6a8d19e0a" + integrity sha512-23H9YxiIo3Jt9vyygjHm985V2ByVjozA8M4Tw3rrXFu0wSHnlV86P4ZZVnM3zzDTA2AgBXsEkC9AIkHiyrKNMQ== + dependencies: + "@react-native-aria/interactions" "^0.2.10" + tsconfig "7" + typescript "^4.9.4" + "@gluestack-ui/provider@^0.1.6", "@gluestack-ui/provider@latest": version "0.1.7" resolved "https://registry.yarnpkg.com/@gluestack-ui/provider/-/provider-0.1.7.tgz#d71783c70cbfbac9a5dd0b1006e8dae66818b6a3" @@ -1900,7 +2052,7 @@ tsconfig "7" typescript "^4.9.4" -"@gluestack-ui/radio@latest": +"@gluestack-ui/radio@^0.1.18", "@gluestack-ui/radio@latest": version "0.1.18" resolved "https://registry.yarnpkg.com/@gluestack-ui/radio/-/radio-0.1.18.tgz#7cd830b00d9dd8cfeab51b6eaaefa5299c1b7f88" integrity sha512-CvohSYYAsjakRdUMEKnj9yitOPDyTyVwlbpJnQmfa3+iSOwPzvm7o8FRgTHJ/506f27yvvq2ygh80IvJroD9Mw== @@ -1921,7 +2073,7 @@ "@react-native-aria/focus" "^0.2.7" react-native-svg "13.4.0" -"@gluestack-ui/select@latest": +"@gluestack-ui/select@^0.1.14", "@gluestack-ui/select@latest": version "0.1.14" resolved "https://registry.yarnpkg.com/@gluestack-ui/select/-/select-0.1.14.tgz#484d668fd71c70d65f5c8cfb18964f21ebf80a28" integrity sha512-N2cyzl3MhIQgnKdqY3o5SikdstQXu8VNAYXTQ7N3TVN6nGqoVpWKGlgmz9yt+xQtTH6+2hNkdnjR6sMPdG3leQ== @@ -1931,6 +2083,19 @@ "@gluestack-ui/utils" "^0.1.5" "@react-native-aria/focus" "^0.2.7" +"@gluestack-ui/slider@^0.1.11": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@gluestack-ui/slider/-/slider-0.1.12.tgz#466e2cf05eeb31d822180851d1f3e586b80523f6" + integrity sha512-f134ojh2bKtGD6eDvcTmPjhBePGTO1Mf8JdG2VeULnc22qdKVqoNbfs9Ed8PmmzzHHcy2WuKUdN8sKVMQMPokg== + dependencies: + "@gluestack-ui/form-control" "^0.1.10" + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/utils" "^0.1.9" + "@react-aria/visually-hidden" "^3.8.1" + "@react-native-aria/interactions" "^0.2.8" + "@react-native-aria/slider" "^0.2.7" + "@react-stately/slider" "^3.2.4" + "@gluestack-ui/slider@latest": version "0.1.10" resolved "https://registry.yarnpkg.com/@gluestack-ui/slider/-/slider-0.1.10.tgz#77197a58e978f3af688400d5a28897f03faea694" @@ -1944,12 +2109,17 @@ "@react-native-aria/slider" "^0.2.5-alpha.2" "@react-stately/slider" "^3.2.4" +"@gluestack-ui/spinner@^0.1.10": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@gluestack-ui/spinner/-/spinner-0.1.10.tgz#9da7c9d4c85a493585adde769f56500ce16f5f96" + integrity sha512-pTUQzA+bzE3ZqnijqVoJqbVlbZWs8TxdVwyju1RAw7QcEGiQh1Eo1Jpe+A5Ic50NvgdsQmsGpGm0QM3NNl6W7A== + "@gluestack-ui/spinner@latest": version "0.1.8" resolved "https://registry.yarnpkg.com/@gluestack-ui/spinner/-/spinner-0.1.8.tgz#4f5f6ee9c3f0a6dea8cca83a1415488f8e42bc46" integrity sha512-wwyMLyxi20iZXHKKIQUQSXP1Ng5ds8eeFj47GvCIwjhGqtFVuQc7aM8IZbtQ0pkQRmJcpjzIPjRo6QIABct0ZA== -"@gluestack-ui/switch@latest": +"@gluestack-ui/switch@^0.1.12", "@gluestack-ui/switch@latest": version "0.1.12" resolved "https://registry.yarnpkg.com/@gluestack-ui/switch/-/switch-0.1.12.tgz#7ec84190284cf32d49590ea7a3a067fa4db7cf36" integrity sha512-pGh5lihijI/IUHyN6Wl9En3YLPfRrNSeR7Wc7YJljZjPzIpWHqYEB173IMhxdJWveIhfPFIDSDeu5VarItJGyg== @@ -1960,7 +2130,7 @@ "@react-native-aria/interactions" "^0.2.8" "@react-stately/toggle" "^3.4.4" -"@gluestack-ui/tabs@latest": +"@gluestack-ui/tabs@^0.1.11", "@gluestack-ui/tabs@latest": version "0.1.11" resolved "https://registry.yarnpkg.com/@gluestack-ui/tabs/-/tabs-0.1.11.tgz#4d0269b9064adc343c94aad8940c87f11bba7270" integrity sha512-/zXn5G7sPViNtWGtBDC8cl+QyE88vqfjio2P0IOZ77bzSA9ddA7SrMIhvHpvyy+kdWs5K8sElApXb6tAwFIi6w== @@ -1969,6 +2139,15 @@ "@react-native-aria/focus" "^0.2.8" "@react-native-aria/interactions" "^0.2.10" +"@gluestack-ui/textarea@^0.1.13": + version "0.1.13" + resolved "https://registry.yarnpkg.com/@gluestack-ui/textarea/-/textarea-0.1.13.tgz#5224927cd08d09b9073a33255282708b4f93184c" + integrity sha512-cS9hWB4xemCTV6QJ9Ol5K6LYKma+gQeoXy8tcpsJzD1ucr07psI08+Zwya3nDk7E7rqrjKK6rgoImfn8FJyCgQ== + dependencies: + "@gluestack-ui/form-control" "^0.1.10" + "@gluestack-ui/utils" "^0.1.9" + "@react-native-aria/focus" "^0.2.7" + "@gluestack-ui/textarea@latest": version "0.1.12" resolved "https://registry.yarnpkg.com/@gluestack-ui/textarea/-/textarea-0.1.12.tgz#9f544ba9b7aa43e78a2ec11c9894d7b3abe04a44" @@ -1979,6 +2158,59 @@ "@react-native-aria/focus" "^0.2.7" react-native-svg "13.4.0" +"@gluestack-ui/themed@^0.1.46-alpha.1": + version "0.1.46-alpha.1" + resolved "https://registry.yarnpkg.com/@gluestack-ui/themed/-/themed-0.1.46-alpha.1.tgz#1ff2f21941efc540adab9fc7b4c52fd2d8cfb038" + integrity sha512-yPFafDYGmJhMvSgtNYc3U4P31IIJ3SJ58AglNvK81Tkj3wCYOVueapjHYSNhSjfP5JQf0OjApe08iiTFwpJ4iw== + dependencies: + "@expo/html-elements" latest + "@gluestack-style/animation-plugin" "^0.1.12" + "@gluestack-style/animation-resolver" "^0.0.1" + "@gluestack-style/legend-motion-animation-driver" "^0.0.1" + "@gluestack-ui/actionsheet" "^0.2.20" + "@gluestack-ui/alert" "^0.1.8" + "@gluestack-ui/alert-dialog" "^0.1.16" + "@gluestack-ui/avatar" "^0.1.10" + "@gluestack-ui/button" "^0.1.25" + "@gluestack-ui/checkbox" "^0.1.17" + "@gluestack-ui/divider" "^0.1.5" + "@gluestack-ui/fab" "^0.1.12" + "@gluestack-ui/form-control" "^0.1.10" + "@gluestack-ui/hstack" "^0.1.11" + "@gluestack-ui/icon" "^0.1.9" + "@gluestack-ui/image" "^0.1.1" + "@gluestack-ui/input" "^0.1.16" + "@gluestack-ui/link" "^0.1.10" + "@gluestack-ui/menu" "^0.2.19" + "@gluestack-ui/modal" "^0.1.20" + "@gluestack-ui/overlay" "^0.1.8" + "@gluestack-ui/popover" "^0.1.21" + "@gluestack-ui/pressable" "^0.1.9" + "@gluestack-ui/progress" "^0.1.7" + "@gluestack-ui/provider" "0.1.9" + "@gluestack-ui/radio" "^0.1.18" + "@gluestack-ui/select" "^0.1.14" + "@gluestack-ui/slider" "^0.1.11" + "@gluestack-ui/spinner" "^0.1.10" + "@gluestack-ui/switch" "^0.1.12" + "@gluestack-ui/tabs" "^0.1.11" + "@gluestack-ui/textarea" "^0.1.13" + "@gluestack-ui/toast" "^0.1.15" + "@gluestack-ui/tooltip" "^0.1.17" + "@gluestack-ui/vstack" "^0.1.11" + "@legendapp/motion" latest + +"@gluestack-ui/toast@^0.1.15": + version "0.1.15" + resolved "https://registry.yarnpkg.com/@gluestack-ui/toast/-/toast-0.1.15.tgz#226153f73ab1c3b5536926bcaaabbaeeb2d7b9d9" + integrity sha512-Ogo56WJXTyJ/gSHfimI6/dJHYukDVzmZ5uSfxRGl6YhWWEW24HKyWbvn7IOsZUwWUPbCZl91JFxCBZ2H9NAc7w== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/transitions" "^0.1.8" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/focus" "^0.2.7" + "@gluestack-ui/toast@latest": version "0.1.14" resolved "https://registry.yarnpkg.com/@gluestack-ui/toast/-/toast-0.1.14.tgz#e13501f4764017cb1036d0c4f394010982bb19d3" @@ -1990,6 +2222,18 @@ "@gluestack-ui/utils" "^0.1.5" "@react-native-aria/focus" "^0.2.7" +"@gluestack-ui/tooltip@^0.1.17": + version "0.1.18" + resolved "https://registry.yarnpkg.com/@gluestack-ui/tooltip/-/tooltip-0.1.18.tgz#0c4832c32ce973a160ddf09e68afc31ca658d0e4" + integrity sha512-dWU31ic+AgSB5k/Yn7Fb3YgwxZbaXpFUiOOqLmzY79e60uH6LWXpC27QxAFkBKisQj0X5eqSzL5hBJzmJ8XNkQ== + dependencies: + "@gluestack-ui/hooks" "^0.1.2" + "@gluestack-ui/overlay" "^0.1.7" + "@gluestack-ui/utils" "^0.1.5" + "@react-native-aria/focus" "^0.2.7" + "@react-native-aria/interactions" "^0.2.10" + "@react-native-aria/overlays" "0.3.7" + "@gluestack-ui/tooltip@latest": version "0.1.15" resolved "https://registry.yarnpkg.com/@gluestack-ui/tooltip/-/tooltip-0.1.15.tgz#cf722b4574cc9ad89c763a60b6ab2ec85e90b9b7" @@ -2021,6 +2265,20 @@ "@react-native-aria/focus" "^0.2.7" react-native-svg "13.4.0" +"@gluestack-ui/utils@0.1.9", "@gluestack-ui/utils@^0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@gluestack-ui/utils/-/utils-0.1.9.tgz#16d362e0fc9eda64f8d855f90d9d63c84dbb3c0e" + integrity sha512-VG0ai84YHuWpePDoa+UrgJTFERJBXbM3rGPRCtHIMjvGMWviyzQXSVU7k5iu5YUgaLhADSK+c/pww9bK9MZzgw== + dependencies: + "@react-native-aria/focus" "^0.2.7" + +"@gluestack-ui/vstack@^0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@gluestack-ui/vstack/-/vstack-0.1.11.tgz#509e8061f91b246d7da69dbd04b98e8462699743" + integrity sha512-WFwhY3qVUuEVukx4rT+1crFMzrh3uQ3/mgwmJ1Mrr7jnWsttKivNrTjju3jyVTBgQJkLHuyFFL18dus8bVb5nA== + dependencies: + "@gluestack-ui/utils" "^0.1.5" + "@gluestack-ui/vstack@latest": version "0.1.9" resolved "https://registry.yarnpkg.com/@gluestack-ui/vstack/-/vstack-0.1.9.tgz#1e01e50dc97e6e6776974d7bc00280ab41f3523f" @@ -2597,6 +2855,19 @@ "@react-native-aria/utils" "^0.2.6" "@react-stately/slider" "^3.0.1" +"@react-native-aria/slider@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@react-native-aria/slider/-/slider-0.2.7.tgz#ab79052388a64afe5818be05bd0b915214ff2007" + integrity sha512-9SacbsDHz8TlLJsC69dRpP15BhDv2sV1LtffVJvwufRoFCdKvEzYyWA6Mu7GxWQR7OoTzl4kYvP0IEArNAgczA== + dependencies: + "@react-aria/focus" "^3.2.3" + "@react-aria/interactions" "^3.3.2" + "@react-aria/label" "^3.1.1" + "@react-aria/slider" "^3.0.1" + "@react-aria/utils" "^3.6.0" + "@react-native-aria/utils" "^0.2.8" + "@react-stately/slider" "^3.0.1" + "@react-native-aria/toggle@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@react-native-aria/toggle/-/toggle-0.2.3.tgz#a387f03480aa0d97dc0191acbcae66122f7bcf7f" diff --git a/packages/animation-plugin/.gitignore b/packages/animation-legend-motion-driver/.gitignore similarity index 100% rename from packages/animation-plugin/.gitignore rename to packages/animation-legend-motion-driver/.gitignore diff --git a/packages/animation-plugin/.nvmrc b/packages/animation-legend-motion-driver/.nvmrc similarity index 100% rename from packages/animation-plugin/.nvmrc rename to packages/animation-legend-motion-driver/.nvmrc diff --git a/packages/animation-plugin/CHANGELOG.md b/packages/animation-legend-motion-driver/CHANGELOG.md similarity index 100% rename from packages/animation-plugin/CHANGELOG.md rename to packages/animation-legend-motion-driver/CHANGELOG.md diff --git a/packages/animation-legend-motion-driver/README.md b/packages/animation-legend-motion-driver/README.md new file mode 100644 index 000000000..87edaa29f --- /dev/null +++ b/packages/animation-legend-motion-driver/README.md @@ -0,0 +1,19 @@ +# @gluestack-style/legend-motion-animation-driver + +## Installation + +To use `@gluestack-style/legend-motion-animation-driver`, all you need to do is install the +`@gluestack-style/legend-motion-animation-driver` package: + +```sh +$ yarn add @gluestack-style/legend-motion-animation-driver + +# or + +$ npm i @gluestack-style/legend-motion-animation-driver +``` + +## Usage + +More guides on how to get started are available +[here](https://gluestack.io/style). diff --git a/packages/animation-plugin/babel.config.js b/packages/animation-legend-motion-driver/babel.config.js similarity index 100% rename from packages/animation-plugin/babel.config.js rename to packages/animation-legend-motion-driver/babel.config.js diff --git a/packages/animation-legend-motion-driver/package.json b/packages/animation-legend-motion-driver/package.json new file mode 100644 index 000000000..5fcec3c2c --- /dev/null +++ b/packages/animation-legend-motion-driver/package.json @@ -0,0 +1,58 @@ +{ + "name": "@gluestack-style/legend-motion-animation-driver", + "version": "1.0.1", + "description": "A gluestack-style plugin for animation support using legendapp motion library", + "keywords": [ + "react", + "native", + "react-native", + "animation", + "legendapp", + "motion", + "driver", + "transition" + ], + "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" + }, + "peerDependencies": { + "@gluestack-style/react": ">=0.2", + "@legendapp/motion": ">=2.2" + }, + "devDependencies": { + "@gluestack-style/react": "^1.0.1", + "@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/" + ] +} diff --git a/packages/animation-legend-motion-driver/src/index.tsx b/packages/animation-legend-motion-driver/src/index.tsx new file mode 100644 index 000000000..0a0333cc3 --- /dev/null +++ b/packages/animation-legend-motion-driver/src/index.tsx @@ -0,0 +1,215 @@ +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 { + Motion, + AnimatePresence as MotionAnimatePresence, + createMotionAnimatedComponent, +} from '@legendapp/motion'; +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) : []; + + const restProps = { ...props }; + + const variantProps: any = {}; + variantTypes?.forEach((variant) => { + if (props[variant]) { + variantProps[variant] = props[variant]; + // delete restProps[variant]; + } + }); + + return { + variantProps, + restProps, + }; +} + +function resolveVariantAnimationProps(variantProps: any, styledObject: any) { + let resolvedVariant = {}; + Object.keys(variantProps).forEach((variant) => { + const variantValue = variantProps[variant]; + const variantObject = styledObject?.variants?.[variant]?.[variantValue]; + + resolvedVariant = deepMerge(resolvedVariant, variantObject); + }); + + return resolvedVariant; +} + +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 + ); + + const config = CONFIG; + + const variantStyledObject = 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 clonedChild = React.cloneElement(child, { + ...restProps, + exit: mergedAnimatedProps?.baseStyle?.[':exit'], + }); + clonedChildren.push(clonedChild); + } else { + clonedChildren.push(child); + } + }); + + return ( + + {clonedChildren} + + ); + } +); + +const AnimatedPressable = createMotionAnimatedComponent( + Pressable +) as React.ComponentType; +export class MotionAnimationDriver implements IAnimationDriverPlugin { + name: 'MotionAnimationDriver'; + engine = { ...Motion, Pressable: AnimatedPressable, AnimatePresence }; + config = { + aliases: { + ':animate': 'animate', + ':initial': 'initial', + ':exit': 'exit', + ':initialProps': 'initialProps', + ':animateProps': 'animateProps', + ':transition': 'transition', + ':transformOrigin': 'transformOrigin', + ':whileTap': 'whileTap', + ':whileHover': 'whileHover', + ':onAnimationComplete': 'onAnimationComplete', + } as const, + }; + + register(config: any) { + if (this.config) { + this.config.aliases = { + ...this.config?.aliases, + ...config?.aliases, + }; + + // @ts-ignore + this.config.tokens = { + // @ts-ignore + ...this.config?.tokens, + ...config?.tokens, + }; + + // @ts-ignore + this.config.ref = config?.ref; + } + } + + constructor(config?: IAnimationResolver) { + this.register(config); + this.name = 'MotionAnimationDriver'; + this.engine.AnimatePresence.defaultProps = { + ...this.engine.AnimatePresence.defaultProps, + config, + }; + } +} diff --git a/packages/animation-plugin/src/propertyTokenMap.ts b/packages/animation-legend-motion-driver/src/propertyTokenMap.ts similarity index 100% rename from packages/animation-plugin/src/propertyTokenMap.ts rename to packages/animation-legend-motion-driver/src/propertyTokenMap.ts diff --git a/packages/animation-plugin/src/utils.ts b/packages/animation-legend-motion-driver/src/utils.ts similarity index 100% rename from packages/animation-plugin/src/utils.ts rename to packages/animation-legend-motion-driver/src/utils.ts diff --git a/packages/animation-plugin/tsconfig.json b/packages/animation-legend-motion-driver/tsconfig.json similarity index 95% rename from packages/animation-plugin/tsconfig.json rename to packages/animation-legend-motion-driver/tsconfig.json index 7ebd787f0..a72b0b039 100644 --- a/packages/animation-plugin/tsconfig.json +++ b/packages/animation-legend-motion-driver/tsconfig.json @@ -12,7 +12,6 @@ "allowUnreachableCode": false, "allowUnusedLabels": true, "esModuleInterop": true, - "importsNotUsedAsValues": "error", "forceConsistentCasingInFileNames": true, "jsx": "react", "lib": ["esnext", "dom"], diff --git a/packages/animation-moti-driver/.gitignore b/packages/animation-moti-driver/.gitignore new file mode 100644 index 000000000..3d3e2719a --- /dev/null +++ b/packages/animation-moti-driver/.gitignore @@ -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 diff --git a/packages/animation-moti-driver/.nvmrc b/packages/animation-moti-driver/.nvmrc new file mode 100644 index 000000000..5dbac1ed0 --- /dev/null +++ b/packages/animation-moti-driver/.nvmrc @@ -0,0 +1 @@ +v16.13.0 \ No newline at end of file diff --git a/packages/animation-moti-driver/CHANGELOG.md b/packages/animation-moti-driver/CHANGELOG.md new file mode 100644 index 000000000..41be139f9 --- /dev/null +++ b/packages/animation-moti-driver/CHANGELOG.md @@ -0,0 +1,17 @@ +# @gluestack-style/animation-plugin + +## 0.1.7 + +### Patch Changes + +- - Fixed transform array resoltion + +## 0.1.0 + +### Changes + +- Fix forward ref warning +- Fixed variant resolution +- Moved @gluestack-style/react to devDependency +- Add legend motion dependency +- Add variant support diff --git a/packages/animation-moti-driver/README.md b/packages/animation-moti-driver/README.md new file mode 100644 index 000000000..d398d1f62 --- /dev/null +++ b/packages/animation-moti-driver/README.md @@ -0,0 +1,19 @@ +# @gluestack-style/moti-animation-driver + +## Installation + +To use `@gluestack-style/moti-animation-driver`, all you need to do is install the +`@gluestack-style/moti-animation-driver` package: + +```sh +$ yarn add @gluestack-style/moti-animation-driver + +# or + +$ npm i @gluestack-style/moti-animation-driver +``` + +## Usage + +More guides on how to get started are available +[here](https://gluestack.io/style). diff --git a/packages/animation-moti-driver/babel.config.js b/packages/animation-moti-driver/babel.config.js new file mode 100644 index 000000000..fda985a22 --- /dev/null +++ b/packages/animation-moti-driver/babel.config.js @@ -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 + ['@gluestack-style/react']: path.join( + __dirname, + '../react/src/index' + ), + }, + }, + ] + : ['transform-remove-console'], + ], + }; +}; diff --git a/packages/animation-moti-driver/package.json b/packages/animation-moti-driver/package.json new file mode 100644 index 000000000..ccd160a46 --- /dev/null +++ b/packages/animation-moti-driver/package.json @@ -0,0 +1,59 @@ +{ + "name": "@gluestack-style/moti-animation-driver", + "version": "1.0.1", + "description": "A gluestack-style driver for using moti animation with animation resolver plugin.", + "keywords": [ + "react", + "native", + "react-native", + "moti", + "driver", + "animation", + "transition" + ], + "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" + }, + "peerDependencies": { + "@gluestack-style/react": ">=0.2", + "moti": ">=0.26", + "react-native-gesture-handler": ">=2.12", + "react-native-reanimated": ">=3.5" + }, + "devDependencies": { + "@gluestack-style/react": "^0.2.49", + "@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/" + ] +} diff --git a/packages/animation-moti-driver/src/index.tsx b/packages/animation-moti-driver/src/index.tsx new file mode 100644 index 000000000..86df238a5 --- /dev/null +++ b/packages/animation-moti-driver/src/index.tsx @@ -0,0 +1,71 @@ +import type { + IAnimationDriverPlugin, + IAnimationResolver, +} from '@gluestack-style/react'; +import 'react-native-reanimated'; +import 'react-native-gesture-handler'; +import { + MotiImage, + MotiView, + MotiText, + MotiScrollView, + MotiSafeAreaView, + MotiProgressBar, + AnimatePresence, +} from 'moti'; + +let Moti = { + Image: MotiImage, + View: MotiView, + Text: MotiText, + ScrollView: MotiScrollView, + SafeAreaView: MotiSafeAreaView, + ProgressBar: MotiProgressBar, + AnimatePresence, +}; +export class MotiAnimationDriver implements IAnimationDriverPlugin { + name: 'MotiAnimationDriver'; + engine = Moti; + config = { + aliases: { + ':animate': 'animate', + ':initial': 'from', + ':exit': 'exit', + ':initialProps': 'initialProps', + ':animateProps': 'animateProps', + ':transition': 'transition', + ':transformOrigin': 'transformOrigin', + ':whileTap': 'whileTap', + ':whileHover': 'whileHover', + ':onAnimationComplete': 'onAnimationComplete', + } as const, + animatedPropMap: { + x: 'translateX', + y: 'translateY', + } as const, + }; + + register(config: any) { + if (this.config) { + this.config.aliases = { + ...this.config?.aliases, + ...config?.aliases, + }; + + // @ts-ignore + this.config.tokens = { + // @ts-ignore + ...this.config?.tokens, + ...config?.tokens, + }; + + // @ts-ignore + this.config.ref = config?.ref; + } + } + + constructor(config?: IAnimationResolver) { + this.register(config); + this.name = 'MotiAnimationDriver'; + } +} diff --git a/packages/animation-moti-driver/tsconfig.json b/packages/animation-moti-driver/tsconfig.json new file mode 100644 index 000000000..a72b0b039 --- /dev/null +++ b/packages/animation-moti-driver/tsconfig.json @@ -0,0 +1,31 @@ +{ + "include": ["./src"], + "exclude": ["node_modules", "example"], + "path": { + "@gluestack-style/react": ["../react/src"] + }, + "compilerOptions": { + "emitDeclarationOnly": true, + "noEmit": false, + "baseUrl": ".", + "declaration": true, + "allowUnreachableCode": false, + "allowUnusedLabels": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react", + "lib": ["esnext", "dom"], + "module": "esnext", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noStrictGenericChecks": false, + "noUnusedLocals": false, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext" + } +} diff --git a/packages/animation-plugin/README.md b/packages/animation-plugin/README.md deleted file mode 100644 index 3cf303a80..000000000 --- a/packages/animation-plugin/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @gluestack-style/animation-plugin - -## Installation - -To use `@gluestack-style/animation-plugin`, all you need to do is install the -`@gluestack-style/animation-plugin` package: - -```sh -$ yarn add @gluestack-style/animation-plugin - -# or - -$ npm i @gluestack-style/animation-plugin -``` - -## Usage - -You can initialize the Animation plugin by creating a new instance of the AnimationResolver class and providing it as an argument to the createStyled function. The `AnimationResolver` takes an optional `styledUtils` object that maps the styled utils object. Here's an example: - -```jsx -import { createStyled } from '@gluestack-style/react'; -import { AnimationResolver } from '@gluestack-style/animation-plugin'; - -const styled = createStyled([ - new AnimationResolver({ - aliases: { - ':initial': 'initial', - ':animate': 'animate', - ':exit': 'exit', - }, - }), -]); -``` - -In this example, we are creating a new instance of the AnimationResolver class, 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. - -## Example of creating a styled component: - -Once the plugin is initialized, you can use the styled function to create styled components with animation props. Here's an example: - -```jsx -const Box = styled(Motion.View, { - ':initial': { opacity: 0 }, - ':animate': { opacity: 1 }, - ':exit': { opacity: 0 }, -}); -``` - -The final internal styled object that will be resolved is: - -```jsx -styledObject = { - 'props': { - initial: { - opacity: 0, - }, - animate: { - opacity: 1, - }, - exit: { - opacity: 0, - }, - } - }, -}; -``` - -More guides on how to get started are available -[here](https://gluestack.io/style). diff --git a/packages/animation-plugin/src/index.tsx b/packages/animation-plugin/src/index.tsx deleted file mode 100644 index 8ef8ce5f4..000000000 --- a/packages/animation-plugin/src/index.tsx +++ /dev/null @@ -1,379 +0,0 @@ -import React, { useMemo } from 'react'; -import type { IStyled, IStyledPlugin } from '@gluestack-style/react'; -import { useStyled } from '@gluestack-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 (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) : []; - - const restProps = { ...props }; - - const variantProps: any = {}; - variantTypes?.forEach((variant) => { - if (props[variant]) { - variantProps[variant] = props[variant]; - // delete restProps[variant]; - } - }); - - return { - variantProps, - restProps, - }; -} - -function resolveVariantAnimationProps(variantProps: any, styledObject: any) { - let resolvedVariant = {}; - Object.keys(variantProps).forEach((variant) => { - const variantValue = variantProps[variant]; - const variantObject = styledObject?.variants?.[variant]?.[variantValue]; - - resolvedVariant = deepMerge(resolvedVariant, variantObject); - }); - - return resolvedVariant; -} - -export class AnimationResolver implements IStyledPlugin { - name: 'AnimationResolver'; - styledUtils = { - aliases: { - ':animate': 'animate', - ':initial': 'initial', - ':exit': 'exit', - ':initialProps': 'initialProps', - ':animateProps': 'animateProps', - ':transition': 'transition', - ':transformOrigin': 'transformOrigin', - ':whileTap': 'whileTap', - ':whileHover': 'whileHover', - ':onAnimationComplete': 'onAnimationComplete', - } as const, - }; - - register(styledUtils: any) { - if (this.styledUtils) { - this.styledUtils.aliases = { - ...this.styledUtils?.aliases, - ...styledUtils?.aliases, - }; - - // @ts-ignore - this.styledUtils.tokens = { - // @ts-ignore - ...this.styledUtils?.tokens, - ...styledUtils?.tokens, - }; - - // @ts-ignore - this.styledUtils.ref = styledUtils?.ref; - } - } - - constructor(styledUtils?: IStyled) { - this.register(styledUtils); - this.name = 'AnimationResolver'; - } - - #childrenExitPropsMap: any = {}; - - #extendedConfig: any = {}; - - inputMiddleWare( - styledObj = {}, - shouldUpdateConfig: any = true - ): { - // @ts-ignore - [key in keyof typeof this.styledUtils.aliases]: (typeof this.styledUtils.aliases)[key]; - } { - // this.#childrenExitPropsMap = deepClone(styledObj); - const resolvedAnimatedProps = this.updateStyledObject( - styledObj, - shouldUpdateConfig - ); - const resolvedStyledObjectWithAnimatedProps = deepMerge( - styledObj, - resolvedAnimatedProps - ); - - if (shouldUpdateConfig) { - // @ts-ignore - 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(); - } - - // @ts-ignore - if (aliases && aliases?.[prop]) { - if (shouldUpdateConfig) { - // this.#childrenExitPropsMap[prop] = styledObject[prop]; - setObjectKeyValue( - this.#childrenExitPropsMap, - [...keyPath, prop], - styledObject[prop] - ); - } - const value = styledObject[prop]; - // @ts-ignore - keyPath.push('props', aliases[prop]); - setObjectKeyValue(resolvedStyledObject, keyPath, value); - keyPath.pop(); - keyPath.pop(); - delete styledObject[prop]; - } - } - - return resolvedStyledObject; - } - - componentMiddleWare({ Component, ExtendedConfig }: any) { - const styledConfig = this.#childrenExitPropsMap; - - this.#childrenExitPropsMap = {}; - - const NewComponent = React.forwardRef((props: any, ref?: any) => { - const { sx, ...rest } = 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 { variantProps, restProps } = getVariantProps(rest, styledConfig); - const variantStyledObject = resolveVariantAnimationProps( - variantProps, - styledConfig - ); - const componentStyledObject = deepMerge( - variantStyledObject, - 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 - ? // @ts-ignore - resolvedAnimatedStyledWithStyledObject?.props - : {}; - - return ( - - ); - }); - - if (NewComponent) { - //@ts-ignore - NewComponent.styled = {}; - //@ts-ignore - NewComponent.styled.config = {}; - //@ts-ignore - NewComponent.styled.config = styledConfig; - - //@ts-ignore - NewComponent.isStyledComponent = Component?.isStyledComponent; - //@ts-ignore - NewComponent.isComposedComponent = Component?.isComposedComponent; - - NewComponent.displayName = 'StyledComponent'; - return NewComponent; - } - return null; - } - - wrapperComponentMiddleWare() { - const AnimatedPresenceComp = React.forwardRef( - ({ children, ...props }: any, ref?: 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 === 'StyledComponent') { - let tokenizedAnimatedProps: any = {}; - const animationAliases = this.styledUtils?.aliases; - - const componentStyledObject = child?.type?.styled?.config; - const { variantProps, restProps } = getVariantProps( - child?.props, - componentStyledObject - ); - - const config = CONFIG; - - if (child.type.styled.resolvedProps) { - tokenizedAnimatedProps = child?.type?.styled?.resolvedProps; - } else { - const variantStyledObject = resolveVariantAnimationProps( - variantProps, - componentStyledObject - ); - const componentStyledObjectWithVariants = deepMergeObjects( - componentStyledObject, - variantStyledObject - ); - tokenizedAnimatedProps = tokenizeAnimationPropsFromConfig( - componentStyledObjectWithVariants, - 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, { - exit: mergedAnimatedProps?.[':exit'], - ...restProps, - }); - clonedChildren.push(clonedChild); - } else { - clonedChildren.push(child); - } - }); - - return ( - - {clonedChildren} - - ); - } - ); - - AnimatedPresenceComp.displayName = `AnimatePresence`; - - return { - Component: AnimatedPresenceComp, - AnimatePresence: AnimatedPresenceComp, - }; - } -} diff --git a/packages/animation-resolver/.gitignore b/packages/animation-resolver/.gitignore new file mode 100644 index 000000000..3d3e2719a --- /dev/null +++ b/packages/animation-resolver/.gitignore @@ -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 diff --git a/packages/animation-resolver/.nvmrc b/packages/animation-resolver/.nvmrc new file mode 100644 index 000000000..5dbac1ed0 --- /dev/null +++ b/packages/animation-resolver/.nvmrc @@ -0,0 +1 @@ +v16.13.0 \ No newline at end of file diff --git a/packages/animation-resolver/CHANGELOG.md b/packages/animation-resolver/CHANGELOG.md new file mode 100644 index 000000000..41be139f9 --- /dev/null +++ b/packages/animation-resolver/CHANGELOG.md @@ -0,0 +1,17 @@ +# @gluestack-style/animation-plugin + +## 0.1.7 + +### Patch Changes + +- - Fixed transform array resoltion + +## 0.1.0 + +### Changes + +- Fix forward ref warning +- Fixed variant resolution +- Moved @gluestack-style/react to devDependency +- Add legend motion dependency +- Add variant support diff --git a/packages/animation-resolver/README.md b/packages/animation-resolver/README.md new file mode 100644 index 000000000..4799ef737 --- /dev/null +++ b/packages/animation-resolver/README.md @@ -0,0 +1,25 @@ +# @gluestack-style/animation-resovler + +## Installation + +To use `@gluestack-style/animation-resovler`, all you need to do is install the +`@gluestack-style/animation-resovler` package: + +```sh +$ yarn add @gluestack-style/animation-resovler + +# or + +$ npm i @gluestack-style/animation-resovler +``` + +## Usage + +In this example, we are creating a new instance of the AnimationResolver class, 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. + +## Example of creating a styled component: + +Once the plugin is initialized, you can use the styled function to create styled components with animation props. Here's an example: + +More guides on how to get started are available +[here](https://style.gluestack.io/). diff --git a/packages/animation-resolver/babel.config.js b/packages/animation-resolver/babel.config.js new file mode 100644 index 000000000..fda985a22 --- /dev/null +++ b/packages/animation-resolver/babel.config.js @@ -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 + ['@gluestack-style/react']: path.join( + __dirname, + '../react/src/index' + ), + }, + }, + ] + : ['transform-remove-console'], + ], + }; +}; diff --git a/packages/animation-plugin/package.json b/packages/animation-resolver/package.json similarity index 77% rename from packages/animation-plugin/package.json rename to packages/animation-resolver/package.json index df7c6d2d1..7b52fff12 100644 --- a/packages/animation-plugin/package.json +++ b/packages/animation-resolver/package.json @@ -1,7 +1,7 @@ { - "name": "@gluestack-style/animation-plugin", - "version": "0.1.12", - "description": "A gluestack-style plugin for animation properties, utilizing animation libraries.", + "name": "@gluestack-style/animation-resolver", + "version": "1.0.1", + "description": "A gluestack-style plugin for resolving animation properties, utilizing animation libraries.", "keywords": [ "react", "native", @@ -21,11 +21,11 @@ "build": "bob build", "clean": "rm -rf lib" }, - "dependencies": { - "@legendapp/motion": "^2.2.0" + "peerDependencies": { + "@gluestack-style/react": ">=0.2" }, "devDependencies": { - "@gluestack-style/react": "^0.1.11", + "@gluestack-style/react": "^0.2.49", "@types/react": "^18.0.22", "@types/react-native": "^0.69.15", "babel-plugin-transform-remove-console": "^6.9.4", diff --git a/packages/animation-resolver/src/AnimatedComponents/index.tsx b/packages/animation-resolver/src/AnimatedComponents/index.tsx new file mode 100644 index 000000000..b472f8b45 --- /dev/null +++ b/packages/animation-resolver/src/AnimatedComponents/index.tsx @@ -0,0 +1,123 @@ +import React from 'react'; +import { useStyled } from '@gluestack-style/react'; +import type { + ImageProps, + PressableProps, + ViewProps, + TextProps, + ScrollViewProps, + FlatListProps, + SectionListProps, +} from 'react-native'; + +const getAnimationResolverPlugin: any = (plugins: any[]) => { + let pluginData; + plugins.forEach((plugin) => { + if (plugin.name === 'AnimationResolver') { + pluginData = plugin; + } + }); + + return pluginData; +}; + +const animatedComponent = (componentName: string, _props: any) => { + return React.forwardRef(({ ...props }: any, ref: any) => { + const ctx = useStyled(); + // let animationDriverData = ctx?.config?.plugins[0]?.componentDriver; + + let animationDriverData: any = getAnimationResolverPlugin( + ctx?.config?.plugins + )?.componentDriver; + + if (animationDriverData?.engine[componentName]) { + const Component = animationDriverData.engine[componentName]; + return ; + } + return ; + }); +}; + +const AnimatedText = ( + props: TextProps & { + animationComponentGluestack: true; + } +) => { + const Component = animatedComponent('Text', props); + return ; +}; +const AnimatedView = ( + props: ViewProps & { + animationComponentGluestack: true; + } +) => { + const Component = animatedComponent('props', props); + return ; +}; + +const AnimatedPressable = ( + props: PressableProps & { + animationComponentGluestack: true; + } +) => { + // @ts-ignore + const Component = animatedComponent('Pressable', props); + return ; +}; +const AnimatedImage = ( + props: ImageProps & { + animationComponentGluestack: true; + } +) => { + const Component = animatedComponent('Image', props); + return ; +}; +const AnimatedScrollView = ( + props: ScrollViewProps & { animationComponentGluestack: true } +) => { + const Component = animatedComponent('ScrollView', props); + return ; +}; +const AnimatedSafeAreaView = (props: React.PropsWithChildren) => { + const Component = animatedComponent('SafeAreaView', props); + return ; +}; +const AnimatedFlatList = ( + props: FlatListProps & { animationComponentGluestack: true } +) => { + const Component = animatedComponent('FlatList', props); + return ; +}; +const AnimatedSectionList = ( + props: SectionListProps & { animationComponentGluestack: true } +) => { + const Component = animatedComponent('SectionList', props); + return ; +}; +const AnimatePresence = animatedComponent('AnimatePresence', {}); + +AnimatedText.displayName = 'Gluestack-AnimatedResolver-AnimatedText'; +AnimatedView.displayName = 'Gluestack-AnimatedResolver-AnimatedView'; +AnimatedPressable.displayName = 'Gluestack-AnimatedResolver-AnimatedPressable'; +AnimatedImage.displayName = 'Gluestack-AnimatedResolver-AnimatedImage'; +AnimatedScrollView.displayName = + 'Gluestack-AnimatedResolver-AnimatedScrollView'; +AnimatedSafeAreaView.displayName = + 'Gluestack-AnimatedResolver-AnimatedSafeAreaView'; +AnimatedFlatList.displayName = 'Gluestack-AnimatedResolver-AnimatedFlatList'; +AnimatedSectionList.displayName = + 'Gluestack-AnimatedResolver-AnimatedSectionList'; +AnimatePresence.displayName = + 'Gluestack-AnimatedResolver-AnimatedAnimatePresence'; + +export { + AnimatedText, + AnimatedView, + AnimatedPressable, + AnimatedImage, + AnimatedScrollView, + AnimatedSafeAreaView, + AnimatedFlatList, + AnimatedSectionList, + AnimatePresence, +}; diff --git a/packages/animation-resolver/src/index.tsx b/packages/animation-resolver/src/index.tsx new file mode 100644 index 000000000..f46033641 --- /dev/null +++ b/packages/animation-resolver/src/index.tsx @@ -0,0 +1,368 @@ +import React, { useEffect, useMemo } from 'react'; +import type { + // @ts-ignore + IAnimationDriverPlugin, + IStyledPlugin, +} from '@gluestack-style/react'; +import { useStyled } from '@gluestack-style/react'; +import { deepMerge, setObjectKeyValue, resolvedTokenization } from './utils'; +import { propertyTokenMap } from './propertyTokenMap'; + +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) : []; + + const restProps = { ...props }; + + const variantProps: any = {}; + variantTypes?.forEach((variant) => { + if (props[variant]) { + variantProps[variant] = props[variant]; + // delete restProps[variant]; + } + }); + + return { + variantProps, + restProps, + }; +} + +function resolveVariantAnimationProps(variantProps: any, styledObject: any) { + let resolvedVariant = {}; + Object.keys(variantProps).forEach((variant) => { + const variantValue = variantProps[variant]; + const variantObject = styledObject?.variants?.[variant]?.[variantValue]; + + resolvedVariant = deepMerge(resolvedVariant, variantObject); + }); + + return resolvedVariant; +} + +export class AnimationResolver implements IStyledPlugin { + name: 'AnimationResolver'; + componentDriver: IAnimationDriverPlugin; + config = { + aliases: { + ':animate': 'animate', + ':initial': 'initial', + ':exit': 'exit', + ':initialProps': 'initialProps', + ':animateProps': 'animateProps', + ':transition': 'transition', + ':transformOrigin': 'transformOrigin', + ':whileTap': 'whileTap', + ':whileHover': 'whileHover', + ':onAnimationComplete': 'onAnimationComplete', + } as const, + tokens: {} as const, + animatedPropMap: {} as any, + }; + + AnimatePresenceComp = React.Fragment; + + register(config: any) { + if (this.config) { + if (config?.aliases) { + this.config.aliases = { + ...this.config?.aliases, + ...config?.aliases, + }; + } + + if (config?.tokens) { + this.config.tokens = { + ...this.config?.tokens, + ...config?.tokens, + }; + } + if (config?.animatedPropMap) { + this.config.animatedPropMap = { + ...this.config?.animatedPropMap, + ...config?.animatedPropMap, + }; + } + // @ts-ignore + this.config.ref = config?.ref; + } + } + + constructor(ComponentDriverClass: any, config: any = {}) { + // @ts-ignore + const componentDriver = new ComponentDriverClass(config); + this.name = 'AnimationResolver'; + this.componentDriver = componentDriver; + if (componentDriver.engine.AnimatePresence) { + this.AnimatePresenceComp = componentDriver.engine.AnimatePresence; + } + this.register(componentDriver.config); + } + + #childrenExitPropsMap: any = {}; + + #extendedConfig: any = {}; + + inputMiddleWare

( + styledObj = {}, + shouldUpdateConfig: any = true, + _?: boolean, + Component?: React.ComponentType + ): { + // @ts-ignore + [key in keyof typeof this.config.aliases]: P[(typeof this.config.aliases)[key]]; + } { + if ( + Component && + (Component.displayName?.startsWith( + 'Gluestack-AnimatedResolver-Animated' + ) || + // @ts-ignore + Component.isAnimatedComponent) + ) { + let AnimatedComponent = + this.componentDriver.engine[ + // @ts-ignore + Component.displayName?.replace( + 'Gluestack-AnimatedResolver-Animated', + '' + ) + ]; + + if (AnimatedComponent) { + AnimatedComponent.isAnimatedComponent = true; + } + if (!AnimatedComponent) { + AnimatedComponent = Component; + } + + // this.#childrenExitPropsMap = deepClone(styledObj); + const resolvedAnimatedProps = this.updateStyledObject( + styledObj, + shouldUpdateConfig + ); + + const resolvedStyledObjectWithAnimatedProps = deepMerge( + styledObj, + resolvedAnimatedProps + ); + + // if (shouldUpdateConfig) { + // // @ts-ignore + // return [styledObj, shouldUpdateConfig, _, AnimatedComponent]; + // } + + // @ts-ignore + + return [ + resolvedStyledObjectWithAnimatedProps, + shouldUpdateConfig, + _, + AnimatedComponent, + ]; + } + // @ts-ignore + return [styledObj, shouldUpdateConfig, _, Component]; + } + + updateStyledObject( + styledObject: any = {}, + shouldUpdateConfig: boolean, + resolvedStyledObject: any = {}, + keyPath: string[] = [] + ) { + const aliases = this.config?.aliases; + const animatedPropMap = this.config?.animatedPropMap; + for (const prop in styledObject) { + if (typeof styledObject[prop] === 'object') { + keyPath.push(prop); + this.updateStyledObject( + styledObject[prop], + shouldUpdateConfig, + resolvedStyledObject, + keyPath + ); + keyPath.pop(); + } + + // @ts-ignore + if (aliases && aliases?.[prop]) { + if (shouldUpdateConfig) { + // this.#childrenExitPropsMap[prop] = styledObject[prop]; + setObjectKeyValue( + this.#childrenExitPropsMap, + [...keyPath, prop], + styledObject[prop] + ); + } + const value = styledObject[prop]; + + if (keyPath[keyPath.length - 1] === 'style') { + keyPath.pop(); + } + // @ts-ignore + keyPath.push('props', aliases[prop]); + // setObjectKeyValue(resolvedStyledObject, keyPath, value); + + setObjectKeyValue(resolvedStyledObject, keyPath, value); + keyPath.pop(); + keyPath.pop(); + // delete styledObject[prop]; + } + + if (animatedPropMap && animatedPropMap[prop]) { + this.renameObjectKey(styledObject, prop, animatedPropMap[prop]); + } + } + return resolvedStyledObject; + } + + renameObjectKey(obj: any, from: string, to: string) { + obj[to] = obj[from]; + delete obj[from]; + return obj; + } + + componentMiddleWare({ Component, ExtendedConfig }: any) { + if (Component && Component?.isAnimatedComponent) { + const styledConfig = this.#childrenExitPropsMap; + + this.#childrenExitPropsMap = {}; + + const NewComponent = React.forwardRef((props: any, ref?: any) => { + const { sx, ...rest } = props; + + const styledContext = useStyled(); + useEffect(() => { + if (!styledContext.animationDriverData) { + styledContext.setAnimationDriverData(this.componentDriver); + } + }, [styledContext]); + const CONFIG = useMemo( + () => ({ + ...styledContext.config, + propertyTokenMap, + }), + [styledContext.config] + ); + this.#extendedConfig = CONFIG; + if (ExtendedConfig) { + this.#extendedConfig = deepMerge(CONFIG, ExtendedConfig); + } + + let tokenizedAnimatedProps: any = {}; + const { variantProps, restProps } = getVariantProps(rest, styledConfig); + const variantStyledObject = resolveVariantAnimationProps( + variantProps, + styledConfig + ); + const componentStyledObject = deepMerge( + variantStyledObject, + styledConfig + ); + + const animationAliases = this.config?.aliases; + + const config = this.#extendedConfig; + + tokenizedAnimatedProps = tokenizeAnimationPropsFromConfig( + componentStyledObject, + config, + animationAliases + ); + + const tokenizedSxAnimationProps: any = tokenizeAnimationPropsFromConfig( + sx, + config, + animationAliases + ); + + const mergedAnimatedProps = deepMerge( + tokenizedAnimatedProps, + tokenizedSxAnimationProps + ); + + // @ts-ignore + const [resolvedAnimatedStyledWithStyledObject, , ,] = + this.inputMiddleWare(mergedAnimatedProps, false, false, Component); + let isState = false; + + Object.keys(restProps?.states ?? {}).forEach((state: any) => { + isState = restProps.states[state] ? true : false; + }); + const animatedProps = !isState + ? // @ts-ignore + resolvedAnimatedStyledWithStyledObject?.props + : {}; + + return ( + + ); + }); + + if (NewComponent) { + //@ts-ignore + NewComponent.styled = {}; + //@ts-ignore + NewComponent.styled.config = {}; + //@ts-ignore + NewComponent.styled.config = styledConfig; + //@ts-ignore + NewComponent.isStyledComponent = Component?.isStyledComponent; + //@ts-ignore + NewComponent.isComposedComponent = Component?.isComposedComponent; + + NewComponent.displayName = Component?.displayName; + return NewComponent; + } + } else { + return Component; + } + } +} + +export * from './AnimatedComponents'; diff --git a/packages/animation-resolver/src/propertyTokenMap.ts b/packages/animation-resolver/src/propertyTokenMap.ts new file mode 100644 index 000000000..0913ca47d --- /dev/null +++ b/packages/animation-resolver/src/propertyTokenMap.ts @@ -0,0 +1,183 @@ +const borderStyles = 'borderStyles'; +const borderWidths = 'borderWidths'; +const colors = 'colors'; +const mediaQueries = 'mediaQueries'; +const opacity = 'opacity'; +const fonts = 'fonts'; +const fontSizes = 'fontSizes'; +const fontWeights = 'fontWeights'; +const letterSpacings = 'letterSpacings'; +const lineHeights = 'lineHeights'; +const radii = 'radii'; +const shadows = 'shadows'; +// const sizes = 'sizes'; +const space = 'space'; +const transitions = 'transitions'; +const zIndices = 'zIndices'; +export const propertyTokenMap = { + gap: space, + gridGap: space, + columnGap: space, + gridColumnGap: space, + rowGap: space, + gridRowGap: space, + inset: space, + insetBlock: space, + insetBlockEnd: space, + insetBlockStart: space, + insetInline: space, + insetInlineEnd: space, + insetInlineStart: space, + margin: space, + marginTop: space, + marginRight: space, + marginBottom: space, + marginLeft: space, + marginBlock: space, + marginBlockEnd: space, + marginBlockStart: space, + marginInline: space, + marginInlineEnd: space, + marginInlineStart: space, + + marginHorizontal: space, + marginVertical: space, + padding: space, + paddingTop: space, + paddingRight: space, + paddingBottom: space, + paddingLeft: space, + + paddingBlock: space, + paddingBlockEnd: space, + paddingBlockStart: space, + paddingInline: space, + paddingInlineEnd: space, + paddingInlineStart: space, + + paddingHorizontal: space, + paddingVertical: space, + paddingStart: space, + paddingEnd: space, + + top: space, + right: space, + bottom: space, + left: space, + scrollMargin: space, + scrollMarginTop: space, + scrollMarginRight: space, + scrollMarginBottom: space, + scrollMarginLeft: space, + scrollMarginX: space, + scrollMarginY: space, + scrollMarginBlock: space, + scrollMarginBlockEnd: space, + scrollMarginBlockStart: space, + scrollMarginInline: space, + scrollMarginInlineEnd: space, + scrollMarginInlineStart: space, + scrollPadding: space, + scrollPaddingTop: space, + scrollPaddingRight: space, + scrollPaddingBottom: space, + scrollPaddingLeft: space, + scrollPaddingX: space, + scrollPaddingY: space, + scrollPaddingBlock: space, + scrollPaddingBlockEnd: space, + scrollPaddingBlockStart: space, + scrollPaddingInline: space, + scrollPaddingInlineEnd: space, + scrollPaddingInlineStart: space, + // shadowOffset: space, + shadowRadius: space, + elevation: space, + + fontSize: fontSizes, + + background: colors, + backgroundColor: colors, + backgroundImage: colors, + borderImage: colors, + border: colors, + borderBlock: colors, + borderBlockEnd: colors, + borderBlockStart: colors, + borderBottom: colors, + borderBottomColor: colors, + borderColor: colors, + borderInline: colors, + borderInlineEnd: colors, + borderInlineStart: colors, + borderLeft: colors, + borderLeftColor: colors, + borderRight: colors, + borderRightColor: colors, + borderTop: colors, + borderTopColor: colors, + caretColor: colors, + color: colors, + columnRuleColor: colors, + fill: colors, + outline: colors, + outlineColor: colors, + stroke: colors, + textDecorationColor: colors, + shadowColor: colors, + + shadowOpacity: opacity, + + shadow: shadows, + // Media Query + condition: mediaQueries, + + fontFamily: fonts, + + fontWeight: fontWeights, + + lineHeight: lineHeights, + + letterSpacing: letterSpacings, + + blockSize: space, + minBlockSize: space, + maxBlockSize: space, + inlineSize: space, + minInlineSize: space, + maxInlineSize: space, + width: space, + minWidth: space, + maxWidth: space, + height: space, + minHeight: space, + maxHeight: space, + flexBasis: space, + gridTemplateColumns: space, + gridTemplateRows: space, + + borderWidth: borderWidths, + borderTopWidth: borderWidths, + borderRightWidth: borderWidths, + borderBottomWidth: borderWidths, + borderLeftWidth: borderWidths, + + borderStyle: borderStyles, + borderTopStyle: borderStyles, + borderRightStyle: borderStyles, + borderBottomStyle: borderStyles, + borderLeftStyle: borderStyles, + + borderRadius: radii, + borderTopLeftRadius: radii, + borderTopRightRadius: radii, + borderBottomRightRadius: radii, + borderBottomLeftRadius: radii, + + boxShadow: colors, + textShadow: shadows, + + transition: transitions, + + zIndex: zIndices, +} as const; diff --git a/packages/animation-resolver/src/utils.ts b/packages/animation-resolver/src/utils.ts new file mode 100644 index 000000000..1c4be87d1 --- /dev/null +++ b/packages/animation-resolver/src/utils.ts @@ -0,0 +1,231 @@ +export const deepClone = (obj: any) => JSON.parse(JSON.stringify(obj)); + +export const deepMerge = (target: any = {}, source: any) => { + for (const key in source) { + if (source.hasOwnProperty(key)) { + if (typeof target[key] === 'object' && typeof source[key] === 'object') { + deepMerge(target[key], source[key]); + } else { + target[key] = source[key]; + } + } + } + return target; +}; + +export const setObjectKeyValue = (obj: any, keys: any, value: any) => { + let current = obj; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (i === keys.length - 1) { + // we've reached the desired key, so update its value + current[key] = value; + } else { + // we're still traversing the object, so create the key if it doesn't exist + if (!current[key]) { + current[key] = {}; + } + current = current[key]; + } + } + return obj; +}; + +export function deepMergeObjects(...objects: any) { + const isObject = (obj: any) => obj && typeof obj === 'object'; + + return objects.reduce((prev: any, obj: any) => { + if (isObject(prev) && isObject(obj)) { + Object.keys(obj).forEach((key) => { + if (isObject(obj[key])) { + if (!prev[key] || !isObject(prev[key])) { + prev[key] = {}; + } + prev[key] = deepMerge(prev[key], obj[key]); + } else { + prev[key] = obj[key]; + } + }); + } + return prev; + }, {}); +} + +export function resolvedTokenization(props: any, config: any) { + const aliasedResolvedProps = resolveAliasesFromConfig(config, props); + const newProps = resolveTokensFromConfig(config, aliasedResolvedProps); + return newProps; +} + +export function resolveAliasesFromConfig(config: any, props: any) { + const aliasResolvedProps: any = {}; + + Object.keys(props).map((key) => { + if (config?.aliases?.[key]) { + aliasResolvedProps[config.aliases?.[key]] = props[key]; + } else { + aliasResolvedProps[key] = props[key]; + } + }); + return aliasResolvedProps; +} + +export function resolveTokensFromConfig(config: any, props: any) { + let newProps: any = {}; + + Object.keys(props).map((prop: any) => { + const value = props[prop]; + + newProps[prop] = getResolvedTokenValueFromConfig( + config, + props, + prop, + value + ); + }); + // console.log('&&&&&', newProps); + + return newProps; +} + +export function getResolvedTokenValueFromConfig( + config: any, + _props: any, + prop: any, + value: any +) { + let resolvedTokenValue = getTokenFromConfig(config, prop, value); + + // Special case for token ends with em on mobile + // This will work for lineHeight and letterSpacing + // console.log('hello from token ends with em on mobile', resolvedTokenValue); + // if ( + // typeof resolvedTokenValue === 'string' && + // resolvedTokenValue.endsWith('em') && + // Platform.OS !== 'web' + // ) { + // const fontSize = getTokenFromConfig(config, 'fontSize', props?.fontSize); + // resolvedTokenValue = + // parseFloat(resolvedTokenValue) * parseFloat(fontSize ?? BASE_FONT_SIZE); + // } + + return resolvedTokenValue; +} + +export const getTokenFromConfig = (config: any, prop: any, value: any) => { + const aliasTokenType = config.propertyTokenMap[prop]; + + // const tokenScale = config?.tokens?.[aliasTokenType]; + let token; + + // resolveStringToken(value, config, config.propertyTokenMap); + if (typeof value === 'string' && value.includes('$')) { + if (config.propertyResolver?.[prop]) { + let transformer = config.propertyResolver?.[prop]; + token = transformer(value, (value1: any, scale = aliasTokenType) => + resolveStringToken(value1, config, config.propertyTokenMap, prop, scale) + ); + } else { + token = resolveStringToken(value, config, config.propertyTokenMap, prop); + } + } else { + if (config.propertyResolver?.[prop]) { + let transformer = config.propertyResolver?.[prop]; + token = transformer(value, (value: any, scale = aliasTokenType) => { + if (typeof value === 'string' && value.includes('$')) { + return resolveStringToken( + value, + config, + config.propertyTokenMap, + prop, + scale + ); + } else { + return value; + } + }); + } else { + token = value; + } + // console.log(token, typeof token, prop, '******'); + } + + return token; +}; + +function isNumeric(str: string) { + return typeof str === 'number' ? true : false; + // return /^[-+]?[0-9]*\.?[0-9]+$/.test(str); +} +export function resolveStringToken( + string: string, + config: any, + tokenScaleMap: any, + propName: any, + scale?: any +) { + let typeofResult = 'string'; + const token_scale = scale ?? tokenScaleMap[propName]; + + const splitTokenBySpace = string.split(' '); + + const result: any = splitTokenBySpace.map((currentToken) => { + let splitCurrentToken = currentToken.split('$'); + + if (currentToken.startsWith('$')) { + splitCurrentToken = splitCurrentToken.slice(1); + } + + if (splitCurrentToken.length > 1) { + const tokenValue = getObjectProperty(config.tokens, splitCurrentToken); + typeofResult = typeof tokenValue; + return tokenValue; + } else { + if (tokenScaleMap[propName]) { + if (!config || !config.tokens) { + throw new Error( + 'You cannot use tokens without wrapping the component with StyledProvider. Please wrap the component with a StyledProvider and pass theme config.' + ); + } + if ( + config?.tokens[token_scale] && + config?.tokens[token_scale].hasOwnProperty(splitCurrentToken[0]) + ) { + const tokenValue = config?.tokens[token_scale][splitCurrentToken[0]]; + typeofResult = typeof tokenValue; + + if (typeof tokenValue !== 'undefined' && tokenValue !== null) { + return tokenValue; + } else { + return ''; + } + } + } + return splitCurrentToken[splitCurrentToken.length - 1]; + } + }); + + let finalResult = result; + + if (finalResult === '') { + return undefined; + } else { + finalResult = result.join(' '); + + if (isNumeric(finalResult) || typeofResult === 'number') { + return parseFloat(finalResult); + } else { + return finalResult; + } + } +} + +export const getObjectProperty = (object: any, keyPath: any) => { + if (!Array.isArray(keyPath)) { + keyPath = [keyPath]; + } + return keyPath.reduce( + (baseObj: any, key: any) => baseObj && baseObj[key], + object + ); +}; diff --git a/packages/animation-resolver/tsconfig.json b/packages/animation-resolver/tsconfig.json new file mode 100644 index 000000000..a72b0b039 --- /dev/null +++ b/packages/animation-resolver/tsconfig.json @@ -0,0 +1,31 @@ +{ + "include": ["./src"], + "exclude": ["node_modules", "example"], + "path": { + "@gluestack-style/react": ["../react/src"] + }, + "compilerOptions": { + "emitDeclarationOnly": true, + "noEmit": false, + "baseUrl": ".", + "declaration": true, + "allowUnreachableCode": false, + "allowUnusedLabels": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react", + "lib": ["esnext", "dom"], + "module": "esnext", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noStrictGenericChecks": false, + "noUnusedLocals": false, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext" + } +} diff --git a/packages/babel-plugin-styled-resolver/package.json b/packages/babel-plugin-styled-resolver/package.json index e3041317a..2250aafd1 100644 --- a/packages/babel-plugin-styled-resolver/package.json +++ b/packages/babel-plugin-styled-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@gluestack-style/babel-plugin-styled-resolver", - "version": "0.2.6", + "version": "1.0.0-alpha.0", "description": "A gluestack-style babel plugin that transpiles your styled function calls and resolves the component styling in build time.", "keywords": [ "css-in-js", @@ -20,7 +20,7 @@ "dev:web": "cd example/native && yarn web --clear" }, "peerDependencies": { - "@gluestack-style/react": "^0.1.11" + "@gluestack-style/react": ">=0.1" }, "devDependencies": { "@babel/cli": "^7.19.3", diff --git a/packages/babel-plugin-styled-resolver/src/index.js b/packages/babel-plugin-styled-resolver/src/index.js index 407909053..2a005fd37 100644 --- a/packages/babel-plugin-styled-resolver/src/index.js +++ b/packages/babel-plugin-styled-resolver/src/index.js @@ -89,6 +89,24 @@ const convertExpressionContainerToStaticObject = ( }; }; +function findThemeAndComponentConfig(node) { + let themeNode = null; + let componentConfigNode = null; + node.forEach((prop) => { + const propKey = prop.key.name ? prop.key.name : prop.key.value; + if (propKey === 'theme') { + themeNode = prop; + } else if (propKey === 'componentConfig') { + componentConfigNode = prop; + } + }); + + return { + themeNode, + componentConfigNode, + }; +} + function addQuotesToObjectKeys(code) { const ast = babel.parse(`var a = ${code}`, { presets: [babelPresetTypeScript], @@ -222,11 +240,97 @@ function getConfig(configPath) { ); } } -function getSurroundingCharacters(string, index) { - let start = Math.max(0, index - 5); - let end = Math.min(string.length, index + 6); - return string.slice(start, end); + +function getBuildTimeParams( + theme, + componentConfig, + extendedConfig, + outputLibrary, + platform, + type +) { + let mergedPropertyConfig = { + ...ConfigDefault?.propertyTokenMap, + ...propertyTokenMap, + }; + let componentExtendedConfig = merge( + {}, + { + ...ConfigDefault, + propertyTokenMap: { ...mergedPropertyConfig }, + } + ); + + if (theme && Object.keys(theme).length > 0) { + const verbosedTheme = convertStyledToStyledVerbosed(theme); + + let componentHash = stableHash({ + ...theme, + ...componentConfig, + }); + + if (outputLibrary) { + componentHash = outputLibrary + '-' + componentHash; + } + + const { styledIds, verbosedStyleIds } = updateOrderUnResolvedMap( + verbosedTheme, + componentHash, + type, + componentConfig, + BUILD_TIME_GLUESTACK_STYLESHEET, + platform + ); + + const toBeInjected = BUILD_TIME_GLUESTACK_STYLESHEET.resolve( + styledIds, + componentExtendedConfig, + {} + ); + + const current_global_map = BUILD_TIME_GLUESTACK_STYLESHEET.getStyleMap(); + + const orderedResolvedTheme = []; + + current_global_map?.forEach((styledResolved) => { + if (styledIds.includes(styledResolved?.meta?.cssId)) { + orderedResolvedTheme.push(styledResolved); + } + }); + + const styleIdsAst = generateObjectAst(verbosedStyleIds); + + const toBeInjectedAst = generateObjectAst(toBeInjected); + + const orderedResolvedAst = generateArrayAst(orderedResolvedTheme); + + const orderedStyleIdsArrayAst = types.arrayExpression( + styledIds?.map((cssId) => types.stringLiteral(cssId)) + ); + + const resultParamsNode = types.objectExpression([ + types.objectProperty( + types.stringLiteral('orderedResolved'), + orderedResolvedAst + ), + types.objectProperty( + types.stringLiteral('toBeInjected'), + toBeInjectedAst + ), + types.objectProperty( + types.stringLiteral('styledIds'), + orderedStyleIdsArrayAst + ), + types.objectProperty( + types.stringLiteral('verbosedStyleIds'), + styleIdsAst + ), + ]); + return resultParamsNode; + } + return null; } + function getExportedConfigFromFileString(fileData) { if (!fileData) { return {}; @@ -375,6 +479,48 @@ function getIdentifiersObjectFromAstNode(node) { ); } +function generateObjectAst(obj) { + let properties = Object.entries(obj).map(([key, value]) => { + if (typeof value === 'undefined') { + return; + } else if (typeof value === 'object' && !Array.isArray(value)) { + return types.objectProperty( + types.stringLiteral(key), + generateObjectAst(value) + ); + } else if (typeof value === 'object' && Array.isArray(value)) { + let elements = value.map((obj) => { + if (typeof obj === 'string') { + return types.stringLiteral(obj); + } else { + return generateObjectAst(obj); + } + }); + return types.objectProperty( + types.stringLiteral(key), + types.arrayExpression(elements) + ); + } else if (typeof value === 'boolean') { + return types.objectProperty( + types.stringLiteral(key), + types.booleanLiteral(value) + ); + } else { + return types.objectProperty( + types.stringLiteral(key), + typeof value === 'number' + ? types.numericLiteral(value) + : types.stringLiteral(value) + ); + } + }); + + return types.objectExpression(properties.filter((property) => property)); +} +function generateArrayAst(arr) { + return types.arrayExpression(arr.map((obj) => generateObjectAst(obj))); +} + function isImportedFromLibrary(libraries, importName) { if (libraries.includes(importName)) { return true; @@ -406,41 +552,6 @@ let ConfigDefault = CONFIG; module.exports = function (b) { const { types: t } = b; - function generateObjectAst(obj) { - let properties = Object.entries(obj).map(([key, value]) => { - if (typeof value === 'undefined') { - return; - } else if (typeof value === 'object' && !Array.isArray(value)) { - return t.objectProperty(t.stringLiteral(key), generateObjectAst(value)); - } else if (typeof value === 'object' && Array.isArray(value)) { - let elements = value.map((obj) => { - if (typeof obj === 'string') { - return t.stringLiteral(obj); - } else { - return generateObjectAst(obj); - } - }); - return t.objectProperty( - t.stringLiteral(key), - t.arrayExpression(elements) - ); - } else if (typeof value === 'boolean') { - return t.objectProperty(t.stringLiteral(key), t.booleanLiteral(value)); - } else { - return t.objectProperty( - t.stringLiteral(key), - typeof value === 'number' - ? t.numericLiteral(value) - : t.stringLiteral(value) - ); - } - }); - - return t.objectExpression(properties.filter((property) => property)); - } - function generateArrayAst(arr) { - return t.arrayExpression(arr.map((obj) => generateObjectAst(obj))); - } function checkWebFileExists(filePath) { if (filePath.includes('node_modules')) { return false; @@ -469,6 +580,10 @@ module.exports = function (b) { let isStyledPathConfigured = false; let isComponentsPathConfigured = false; let targetPlatform = process.env.GLUESTACK_STYLE_TARGET; + let createStyleImportedName = ''; + let createComponentsImportedName = ''; + const CREATE_STYLE = 'createStyle'; + const CREATE_COMPONENTS = 'createComponents'; return { name: 'ast-transform', // not required @@ -554,6 +669,15 @@ module.exports = function (b) { if (importSpecifierPath.node.imported.name === 'styled') { styledImportName = importSpecifierPath.node.local.name; } + if (importSpecifierPath.node.imported.name === CREATE_STYLE) { + createStyleImportedName = importSpecifierPath.node.local.name; + } + if ( + importSpecifierPath.node.imported.name === CREATE_COMPONENTS + ) { + createComponentsImportedName = + importSpecifierPath.node.local.name; + } if (importSpecifierPath.node.imported.name === styledAlias) { styledAliasImportedName = importSpecifierPath.node.local.name; } @@ -575,28 +699,35 @@ module.exports = function (b) { } } }, - CallExpression(callExpressionPath) { - if ( - callExpressionPath.node.callee.name === styledAliasImportedName || - callExpressionPath.node.callee.name === styledImportName - ) { - let componentName = callExpressionPath?.parent?.id?.name; - - if (componentName) { - guessingStyledComponents.push(componentName); - } - callExpressionPath.traverse({ - ObjectProperty(ObjectPath) { - if (t.isIdentifier(ObjectPath.node.value)) { - if (ObjectPath.node.value.name === 'undefined') { - ObjectPath.remove(); + if (isValidConfig) { + const calleeName = callExpressionPath.node.callee.name; + if ( + calleeName === styledAliasImportedName || + calleeName === styledImportName || + calleeName === createComponentsImportedName || + calleeName === createStyleImportedName + ) { + callExpressionPath.traverse({ + ObjectProperty(ObjectPath) { + if (t.isIdentifier(ObjectPath.node.value)) { + if (ObjectPath.node.value.name === 'undefined') { + ObjectPath.remove(); + } } - } - }, - }); + }, + }); + } + if ( + calleeName === styledAliasImportedName || + calleeName === styledImportName + ) { + let componentName = callExpressionPath?.parent?.id?.name; + + if (componentName) { + guessingStyledComponents.push(componentName); + } - if (isValidConfig) { let args = callExpressionPath.node.arguments; let componentThemeNode = args[1]; @@ -633,89 +764,16 @@ module.exports = function (b) { extendedThemeNode.properties.push(tempPropertyResolverNode); } - // getExportedConfigFromFileString(ConfigDefault); - let mergedPropertyConfig = { - ...ConfigDefault?.propertyTokenMap, - ...propertyTokenMap, - }; - let componentExtendedConfig = merge( - {}, - { - ...ConfigDefault, - propertyTokenMap: { ...mergedPropertyConfig }, - }, - ExtendedConfig + const resultParamsNode = getBuildTimeParams( + theme, + componentConfig, + ExtendedConfig, + outputLibrary, + platform, + 'boot' ); - if (theme && Object.keys(theme).length > 0) { - const verbosedTheme = convertStyledToStyledVerbosed(theme); - - let componentHash = stableHash({ - ...theme, - ...componentConfig, - ...ExtendedConfig, - }); - - if (outputLibrary) { - componentHash = outputLibrary + '-' + componentHash; - } - - const { styledIds, verbosedStyleIds } = - updateOrderUnResolvedMap( - verbosedTheme, - componentHash, - 'boot', - componentConfig, - BUILD_TIME_GLUESTACK_STYLESHEET, - platform - ); - - const toBeInjected = BUILD_TIME_GLUESTACK_STYLESHEET.resolve( - styledIds, - componentExtendedConfig, - ExtendedConfig - ); - - const current_global_map = - BUILD_TIME_GLUESTACK_STYLESHEET.getStyleMap(); - - const orderedResolvedTheme = []; - - current_global_map?.forEach((styledResolved) => { - if (styledIds.includes(styledResolved?.meta?.cssId)) { - orderedResolvedTheme.push(styledResolved); - } - }); - - let styleIdsAst = generateObjectAst(verbosedStyleIds); - - let toBeInjectedAst = generateObjectAst(toBeInjected); - - let orderedResolvedAst = generateArrayAst(orderedResolvedTheme); - - let orderedStyleIdsArrayAst = t.arrayExpression( - styledIds?.map((cssId) => t.stringLiteral(cssId)) - ); - - let resultParamsNode = t.objectExpression([ - t.objectProperty( - t.stringLiteral('orderedResolved'), - orderedResolvedAst - ), - t.objectProperty( - t.stringLiteral('toBeInjected'), - toBeInjectedAst - ), - t.objectProperty( - t.stringLiteral('styledIds'), - orderedStyleIdsArrayAst - ), - t.objectProperty( - t.stringLiteral('verbosedStyleIds'), - styleIdsAst - ), - ]); - + if (resultParamsNode) { while (args.length < 4) { args.push(t.objectExpression([])); } @@ -746,6 +804,92 @@ module.exports = function (b) { // console.log('final', generate(path.node).code); // console.log('\n >>>>>>>>>>>>>>>>>>>>>\n\n'); } + if (calleeName === createStyleImportedName) { + let args = callExpressionPath.node.arguments; + + let componentThemeNode = args[0]; + let componentConfigNode = args[1] ?? t.objectExpression([]); + + if ( + !( + t.isIdentifier(componentThemeNode) || + t.isIdentifier(componentConfigNode) + ) + ) { + let theme = getObjectFromAstNode(componentThemeNode); + let componentConfig = getObjectFromAstNode(componentConfigNode); + + const resultParamsNode = getBuildTimeParams( + theme, + componentConfig, + {}, + outputLibrary, + platform, + 'extended' + ); + + if (resultParamsNode) { + while (args.length < 3) { + args.push(t.objectExpression([])); + } + if (!args[2]) { + args.push(resultParamsNode); + } else { + args[2] = resultParamsNode; + } + } + } + } + if (calleeName === createComponentsImportedName) { + /* + extended theme components AST + { + box: { + theme: {}, + }, + button: { + theme: {}, + }, + } + */ + const extendedThemeComponents = + callExpressionPath.node.arguments[0].properties; + extendedThemeComponents.forEach((property) => { + if ( + !t.isIdentifier(property.value) && + !t.isTemplateLiteral(property.value) && + !t.isConditionalExpression(property.value) + ) { + const { themeNode, componentConfigNode } = + findThemeAndComponentConfig(property.value.properties); + + let theme = themeNode + ? getObjectFromAstNode(themeNode?.value) + : {}; + let componentConfig = componentConfigNode + ? getObjectFromAstNode(componentConfigNode?.value) + : {}; + + const resultParamsNode = getBuildTimeParams( + theme, + componentConfig, + {}, + outputLibrary, + platform, + 'extended' + ); + + if (resultParamsNode) { + property.value.properties.push( + t.objectProperty( + t.stringLiteral('BUILD_TIME_PARAMS'), + resultParamsNode + ) + ); + } + } + }); + } } }, JSXOpeningElement(jsxOpeningElementPath) { diff --git a/packages/react/README.md b/packages/react/README.md index 4770baeae..1879d8ca9 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -10,7 +10,7 @@ ## Documentation -You can find detailed documentation for each component, including a list of props and examples, in https://gluestack.io/styledocs website. +You can find detailed documentation for each component, including a list of props and examples, in https://gluestack.io/style/docs website. ## Installation diff --git a/packages/react/package.json b/packages/react/package.json index fd9c7fe33..f386b944f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,7 +1,7 @@ { "name": "@gluestack-style/react", "description": "A universal & performant styling library for React Native, Next.js & React", - "version": "0.2.51", + "version": "1.0.1", "keywords": [ "React Native", "Next.js", diff --git a/packages/react/src/StyledProvider.tsx b/packages/react/src/StyledProvider.tsx index 91fd4d689..758a9e652 100644 --- a/packages/react/src/StyledProvider.tsx +++ b/packages/react/src/StyledProvider.tsx @@ -9,9 +9,14 @@ import { createGlobalStyles } from './createGlobalStyles'; type Config = any; let colorModeSet = false; -export const defaultConfig: { config: Config; colorMode: COLORMODES } = { +export const defaultConfig: { + config: Config; + colorMode: COLORMODES; + components: any; +} = { config: {}, colorMode: 'light', + components: {}, }; const defaultContextData: Config = defaultConfig; @@ -38,7 +43,7 @@ export const StyledProvider: React.FC<{ children?: React.ReactNode; globalStyles?: any; }> = ({ config, colorMode, children, globalStyles }) => { - const currentConfig = React.useMemo(() => { + const currentConfig: any = React.useMemo(() => { //TODO: Add this later return platformSpecificSpaceUnits(config, Platform.OS); }, [config]); @@ -85,12 +90,18 @@ export const StyledProvider: React.FC<{ setCurrentColorMode(currentColorMode); } + const [animationDriverData, setAnimationDriverData] = React.useState(); const globalStyleMap = config?.globalStyle && createGlobalStyles(config.globalStyle); const contextValue = React.useMemo(() => { - return { config: currentConfig, globalStyle: globalStyleMap }; - }, [currentConfig, globalStyleMap]); + return { + config: currentConfig, + globalStyle: globalStyleMap, + animationDriverData, + setAnimationDriverData, + }; + }, [currentConfig, globalStyleMap, animationDriverData]); return ( diff --git a/packages/react/src/createConfig.ts b/packages/react/src/createConfig.ts index 5aad9322b..5df3a0467 100644 --- a/packages/react/src/createConfig.ts +++ b/packages/react/src/createConfig.ts @@ -5,13 +5,20 @@ import { resolveStringToken } from './utils'; import { stableHash } from './stableHash'; import { propertyTokenMap } from './propertyTokenMap'; import { updateOrderUnResolvedMap } from './updateOrderUnResolvedMap'; +import { GluestackStyleSheet } from './style-sheet'; +import { resolvePlatformTheme } from './styled'; +import { Platform } from 'react-native'; -var globalPluginStore: any = []; +/********************* PLUGINS *****************************/ -function setGlobalPluginStore(plugins: Array) { - globalPluginStore.push(...plugins); +var globalPluginStore: never[] = []; +function setGlobalPluginStore(plugins: any) { + if (plugins) { + // @ts-ignore + globalPluginStore.push(...plugins); + } + return getGlobalPluginStore(); } - function getGlobalPluginStore() { return globalPluginStore; } @@ -20,12 +27,40 @@ export function getInstalledPlugins() { return getGlobalPluginStore(); } +/********************* CREATE COMPONENTS *****************************/ + +var globalComponentsStore: any = {}; + +// function setGlobalComponentsStore(components: any) { +// if (components) { +// // @ts-ignore +// globalComponentsStore = { +// ...globalComponentsStore, +// ...components, +// }; +// } +// return getGlobalComponentsStore(); +// } + +function getGlobalComponentsStore() { + return globalComponentsStore; +} + +export function getInstalledComponents() { + return getGlobalComponentsStore(); +} + +export const createComponents = (components: T): T => { + return components; +}; + export const createConfig = < T extends GlueStackConfig< //@ts-ignore T['tokens'], T['aliases'], - T['globalStyle'] + T['globalStyle'], + T['plugins'] > >( config: @@ -34,32 +69,27 @@ export const createConfig = < //@ts-ignore T['tokens'], T['aliases'], - T['globalStyle'] + T['globalStyle'], + T['plugins'] > ): T => { if (config.plugins) { - setGlobalPluginStore(config.plugins); + config.plugins = setGlobalPluginStore(config.plugins); } - delete config.plugins; + // delete config.plugins; - if ( - !config.components && - // @ts-ignore - !config.themes - ) { + if (!config.themes) { return config as any; } - let newConfig = config; - if (config.components) { - newConfig = resolveComponentThemes(config); - } + // if (config.components) { + // newConfig = resolveComponentThemes(config); + // } - // @ts-ignore if (config.themes) { - const newConfigWithThemesResolved = resolveThemes(newConfig); + const newConfigWithThemesResolved = resolveThemes(config); return newConfigWithThemesResolved as any; } - return newConfig as any; + return config as any; }; const resolveThemes = (config: any) => { @@ -86,36 +116,68 @@ const resolveThemes = (config: any) => { return newConfig; }; -const resolveComponentThemes = (config: any) => { - const newConfig = { ...config }; - delete config.components; +export const resolveComponentTheme = (config: any, componentTheme: any) => { + const configWithPropertyTokenMap = config; + + let resolvedTheme = componentTheme; + const component = componentTheme; + + if ( + Object.keys(component?.BUILD_TIME_PARAMS ?? {}).length === 0 && + component.theme + ) { + resolvedTheme = resolveTheme( + component.theme, + configWithPropertyTokenMap, + component?.componentConfig + ); + } else { + GluestackStyleSheet.update(component.BUILD_TIME_PARAMS?.orderedResolved); + resolvedTheme = component; + } + return resolvedTheme; +}; + +export const resolveComponentThemes = (config: any, components: any) => { + let newComponents: any = {}; const configWithPropertyTokenMap = { ...config, propertyTokenMap, }; - Object.keys(newConfig?.components ?? {}).forEach((componentName: any) => { - const component = newConfig.components[componentName]; - if (component.theme) { - component.theme = resolveTheme( + + Object.keys(components ?? {}).forEach((componentName: any) => { + const component = components[componentName]; + + if ( + Object.keys(component?.BUILD_TIME_PARAMS ?? {}).length === 0 && + component.theme + ) { + newComponents[componentName] = resolveTheme( component.theme, configWithPropertyTokenMap, component?.componentConfig ); + } else { + GluestackStyleSheet.update(component.BUILD_TIME_PARAMS?.orderedResolved); + newComponents[componentName] = component; } }); - return newConfig; + return newComponents; }; -const resolveTheme = ( +export const resolveTheme = ( componentTheme: {}, _config: any, extendedConfig?: any ) => { const versboseComponentTheme = convertStyledToStyledVerbosed(componentTheme); + + resolvePlatformTheme(versboseComponentTheme, Platform.OS); + const componentHash = stableHash({ - ...componentTheme, + ...versboseComponentTheme, }); const { styledIds, verbosedStyleIds } = updateOrderUnResolvedMap( @@ -124,9 +186,10 @@ const resolveTheme = ( 'extended', extendedConfig ); + return { - extendedStyleIds: styledIds, - extendedVerbosedStyleIds: verbosedStyleIds, + styledIds, + verbosedStyleIds, theme: versboseComponentTheme, }; }; diff --git a/packages/react/src/createStyle.ts b/packages/react/src/createStyle.ts new file mode 100644 index 000000000..8db8b45b3 --- /dev/null +++ b/packages/react/src/createStyle.ts @@ -0,0 +1,25 @@ +import type { ViewProps, ImageProps, TextProps } from 'react-native'; +import type { + IComponentStyleConfig, + ITheme, + UnionToIntersection, +} from './types'; + +export const createStyle = ( + theme: T | ITheme, + componentConfig?: Omit, + BUILD_TIME_PARAMS?: any +) => { + const createdStyles = { + theme, + componentConfig, + BUILD_TIME_PARAMS, + }; + + return createdStyles as { + theme: UnionToIntersection< + T | ITheme + >; + componentConfig?: Omit; + }; +}; diff --git a/packages/react/src/createStyled.ts b/packages/react/src/createStyled.ts index 7015d82b0..0dcd72cd3 100644 --- a/packages/react/src/createStyled.ts +++ b/packages/react/src/createStyled.ts @@ -1,19 +1,6 @@ import { styled } from './styled'; import type { IComponentStyleConfig, ITheme } from './types'; -export interface IStyledPlugin { - styledUtils?: IStyled; - register(styledUtils: IStyled): void; - inputMiddleWare(styledObj: any): void; - componentMiddleWare?(props: any): void; -} - -export class IStyled { - aliases?: any; - tokens?: any; - ref?: any; -} - export const createStyled = (plugins: any) => { let styledComponent = ( Component: React.ComponentType

, diff --git a/packages/react/src/generateStylePropsFromCSSIds.ts b/packages/react/src/generateStylePropsFromCSSIds.ts index 35eeaed09..72cdc4c2a 100644 --- a/packages/react/src/generateStylePropsFromCSSIds.ts +++ b/packages/react/src/generateStylePropsFromCSSIds.ts @@ -90,11 +90,7 @@ export function isValidBreakpoint( if (queryWidth.length > 0) { if (queryWidth.length === 1) { - if ( - queryWidth[0] !== null && - // @ts-ignore - queryWidth[0] <= currentBreakpointValue - ) { + if (queryWidth[0] !== null && queryWidth[0] <= currentBreakpointValue) { return true; } } else { @@ -137,7 +133,6 @@ export function generateStylePropsFromCSSIds( config: any, activeTheme: any ) { - // console.setStartTimeStamp('generateStylePropsFromCSSIds'); const propsStyles = Array.isArray(props?.style) ? props?.style : [props?.style]; @@ -174,30 +169,14 @@ export function generateStylePropsFromCSSIds( } } - // console.setEndTimeStamp('generateStylePropsFromCSSIds'); - // return props; - // Object.assign(props., { - // dataSet: - // style: getDataStyle(props, styleCSSIdsString), - // }); - Object.assign(props, { - 'data-style': getDataStyle(props, styleCSSIdsString), 'style': propsStyles ? [...styleObj, ...propsStyles] : styleObj, 'dataSet': { ...props?.dataSet, style: getDataStyle(props, styleCSSIdsString), }, + // DONOT REMOVE THIS LINE, THIS IS FOR SPECIFIC COMPONENTS LIKE next/link + 'data-style': getDataStyle(props, styleCSSIdsString), }); return props; - // return { - // ...props, - // 'dataSet': { - // ...props.dataSet, - // // TODO: this below line causes recalculate style on web - // style: getDataStyle(props, styleCSSIdsString), - // }, - // 'data-style': getDataStyle(props, styleCSSIdsString), - // 'style': propsStyles ? [...styleObj, ...propsStyles] : styleObj, - // }; } diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 38246bd3e..4359ef50f 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -70,19 +70,31 @@ export type { Aliases, AliasesProps, ICustomConfig, + ICustomComponents, + IStyledPlugin, + IStyled, + IAnimationDriverPlugin, GSConfig, + IAnimationResolver, } from './types'; export { createStyled } from './createStyled'; -export type { IStyledPlugin, IStyled } from './createStyled'; + export { createGlobalStylesWeb } from './createGlobalStylesWeb'; // export { styled }; // export { flush } from './utils/css-injector'; - +export { propertyTokenMap } from './propertyTokenMap'; export { AsForwarder } from './AsForwarder'; -export { AddCssTokenVariables, FontResolver } from './plugins'; +export * from './plugins'; + +export { createStyle } from './createStyle'; export { INTERNAL_updateCSSStyleInOrderedResolved } from './updateCSSStyleInOrderedResolved'; -export { createConfig } from './createConfig'; +export { + createConfig, + getInstalledPlugins, + createComponents, + getInstalledComponents, +} from './createConfig'; export * from './core'; export * from './hooks'; diff --git a/packages/react/src/plugins/css-variables.tsx b/packages/react/src/plugins/css-variables.tsx index b3a02520f..a10d5a012 100644 --- a/packages/react/src/plugins/css-variables.tsx +++ b/packages/react/src/plugins/css-variables.tsx @@ -1,4 +1,4 @@ -import type { IStyled, IStyledPlugin } from '../createStyled'; +import type { IStyled, IStyledPlugin } from '../types'; import { deepMerge } from '../utils'; import { injectGlobalCss } from '../utils/css-injector'; import React, { useMemo } from 'react'; diff --git a/packages/react/src/plugins/font-resolver.tsx b/packages/react/src/plugins/font-resolver.tsx index 8ded2b16a..8b5b19a65 100644 --- a/packages/react/src/plugins/font-resolver.tsx +++ b/packages/react/src/plugins/font-resolver.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import type { IStyled, IStyledPlugin } from '../createStyled'; +import type { IStyled, IStyledPlugin } from '../types'; import { useStyled } from '../StyledProvider'; import { propertyTokenMap } from '../propertyTokenMap'; import { deepMerge, deepMergeObjects, setObjectKeyValue } from '../utils'; diff --git a/packages/react/src/styled.tsx b/packages/react/src/styled.tsx index 889bd33c5..301b16911 100644 --- a/packages/react/src/styled.tsx +++ b/packages/react/src/styled.tsx @@ -10,6 +10,7 @@ import type { ITheme, ExtendedConfigType, IComponentStyleConfig, + StyledConfig, } from './types'; import { deepMerge, @@ -43,7 +44,7 @@ import { stableHash } from './stableHash'; import { DeclarationType, GluestackStyleSheet } from './style-sheet'; import { CSSPropertiesMap } from './core/styled-system'; import { updateOrderUnResolvedMap } from './updateOrderUnResolvedMap'; -import { getInstalledPlugins } from './createConfig'; +import { resolveComponentTheme } from './createConfig'; const styledSystemProps = { ...CSSPropertiesMap }; @@ -666,7 +667,7 @@ function mergeArraysInObjects(...objects: any) { return merged; } -function resolvePlatformTheme(theme: any, platform: any) { +export function resolvePlatformTheme(theme: any, platform: any) { if (typeof theme === 'object') { Object.keys(theme).forEach((themeKey) => { if (themeKey !== 'style' && themeKey !== 'defaultProps') { @@ -838,7 +839,7 @@ export function verboseStyled( styledIds: Array; } ) { - const componentName = componentStyleConfig?.componentName; + // const componentName = componentStyleConfig?.componentName; const componentHash = stableHash({ ...theme, ...componentStyleConfig, @@ -860,6 +861,7 @@ export function verboseStyled( //@ts-ignore type ITypeReactNativeStyles = P['style']; let styleHashCreated = false; + let pluginData: any; let orderedResolved: OrderedSXResolved; let componentStyleIds: any = {}; let componentDescendantStyleIds: any = {}; // StyleIds = {}; @@ -973,12 +975,13 @@ export function verboseStyled( let CONFIG: any = {}; let isInjected = false; + let plugins: any = []; const containsDescendant = componentStyleConfig?.descendantStyle && componentStyleConfig?.descendantStyle?.length > 0; - const NewComp = ( + const StyledComponent = ( { children, //@ts-ignore @@ -990,12 +993,15 @@ export function verboseStyled( // styledIds: BUILD_TIME_STYLE_IDS = [], // sxHash: BUILD_TIME_sxHash = '', ...componentProps - }: Omit & - Partial> & - Partial> & { - as?: any; - children?: any; - }, + }: Omit< + Omit & + Partial> & + Partial> & { + as?: any; + children?: any; + }, + 'animationComponentGluestack' + >, ref: React.ForwardedRef

) => { const isClient = React.useRef(false); @@ -1031,33 +1037,76 @@ export function verboseStyled( ...styledContext.config, propertyTokenMap, }; + // for extended components const EXTENDED_THEME = - componentName && CONFIG?.components?.[componentName]?.theme?.theme; + componentStyleConfig.componentName && + CONFIG?.components?.[componentStyleConfig.componentName]; + + // middleware logic // Injecting style if (EXTENDED_THEME) { - theme.variants = deepMerge(theme.variants, EXTENDED_THEME.variants); - theme.defaultProps = deepMerge( - theme.defaultProps, - EXTENDED_THEME.props + // RUN Middlewares + + const resolvedComponentExtendedTheme = resolveComponentTheme( + CONFIG, + EXTENDED_THEME ); + + // const resolvedComponentExtendedTheme = EXTENDED_THEME; + + theme = deepMerge(theme, resolvedComponentExtendedTheme.theme); + // @ts-ignore - theme.props = deepMerge(theme.props, EXTENDED_THEME.props); + Object.assign(themeDefaultProps, theme?.baseStyle?.props); + if (Object.keys(EXTENDED_THEME?.BUILD_TIME_PARAMS ?? {}).length > 0) { + const EXTENDED_THEME_BUILD_TIME_PARAMS = + EXTENDED_THEME?.BUILD_TIME_PARAMS; + deepMergeArray( + styleIds, + EXTENDED_THEME_BUILD_TIME_PARAMS?.verbosedStyleIds + ); + GluestackStyleSheet.inject( + EXTENDED_THEME_BUILD_TIME_PARAMS?.toBeInjected + ); + } else { + // Merge of Extended Config Style ID's with Component Style ID's + deepMergeArray( + styleIds, + resolvedComponentExtendedTheme?.verbosedStyleIds + ); - // Merge of Extended Config Style ID's with Component Style ID's - deepMergeArray( - styleIds, - CONFIG?.components?.[`${componentName}`]?.theme - ?.extendedVerbosedStyleIds - ); - // Injecting Extended StyleSheet from Config - orderedCSSIds = [ - ...orderedCSSIds, - ...CONFIG?.components?.[`${componentName}`]?.theme?.extendedStyleIds, - ]; + const extendedStylesToBeInjected = GluestackStyleSheet.resolve( + resolvedComponentExtendedTheme?.styledIds, + CONFIG, + componentExtendedConfig + ); + GluestackStyleSheet.inject(extendedStylesToBeInjected); + } + } + + if (CONFIG.plugins) { + plugins.push(...CONFIG.plugins); + } + if (ExtendedConfig?.plugins) { + plugins.push(...ExtendedConfig?.plugins); + } + + if (plugins) { + for (const pluginName in plugins) { + // @ts-ignore + [theme, , , Component] = plugins[pluginName]?.inputMiddleWare

( + theme, + true, + true, + Component + ); + } } + // for extended components end + //@ts-ignore const globalStyle = styledContext.globalStyle; @@ -1835,7 +1884,30 @@ export function verboseStyled( delete resolvedStyleProps?.as; + // } + + if (plugins) { + // plugins?.reverse(); + plugins.reverse(); + for (const pluginName in plugins) { + // @ts-ignore + if (plugins[pluginName]?.componentMiddleWare) { + // @ts-ignore + Component = plugins[pluginName]?.componentMiddleWare({ + Component: Component, + theme, + componentStyleConfig, + ExtendedConfig, + }); + + //@ts-ignore + pluginData = Component.styled; + } + } + } + let component; + if (AsComp) { //@ts-ignore if (Component.isStyledComponent) { @@ -1871,12 +1943,14 @@ export function verboseStyled( ); } - // } return component; }; - const StyledComp = React.forwardRef(NewComp); + const StyledComp = React.forwardRef(StyledComponent); + + //@ts-ignore + StyledComp.getStyledData = () => pluginData; const displayName = componentStyleConfig?.componentName ? componentStyleConfig?.componentName @@ -1889,14 +1963,14 @@ export function verboseStyled( //@ts-ignore StyledComp.isStyledComponent = true; - return StyledComp; + return StyledComp as typeof StyledComp & { styledConfig?: StyledConfig }; } -export function styled( +export function styled( Component: React.ComponentType

, theme: ITheme, componentStyleConfig?: IComponentStyleConfig, - ExtendedConfig?: ExtendedConfigType, + ExtendedConfig?: ExtendedConfigType, BUILD_TIME_PARAMS?: { orderedResolved: OrderedSXResolved; verbosedStyleIds: { @@ -1911,19 +1985,46 @@ export function styled( // const DEBUG = // process.env.NODE_ENV === 'development' && DEBUG_TAG ? false : false; - let styledObj = theme; - // @ts-ignore - let plugins: PluginType = [...getInstalledPlugins()]; - if (ExtendedConfig?.plugins) { - // @ts-ignore - plugins = [...plugins, ...ExtendedConfig?.plugins]; + // const componentName = componentStyleConfig?.componentName; + // const componentExtendedTheme = extendedThemeConfig?.theme; + // const componentExtended_build_time_params = + // extendedThemeConfig?.BUILD_TIME_PARAMS; + // let mergedBuildTimeParams: any; + + if (BUILD_TIME_PARAMS) { + // mergedBuildTimeParams = deepMergeArray( + // { ...BUILD_TIME_PARAMS }, + // { ...componentExtended_build_time_params } + // ); } - for (const pluginName in plugins) { - // @ts-ignore - styledObj = plugins[pluginName]?.inputMiddleWare

(styledObj, true, true); - } - theme = styledObj; + // let styledObj = { ...theme }; + // if (componentExtendedTheme) { + // styledObj = deepMerge({ ...theme }, { ...componentExtendedTheme }); + // } + + // // move inside stylehash created + // let plugins = [...getInstalledPlugins()]; + + // if (ExtendedConfig?.plugins) { + // // @ts-ignore + // plugins = [...plugins, ...ExtendedConfig?.plugins]; + // } + + // for (const pluginName in plugins) { + // // @ts-ignore + // [styledObj, , , Component] = plugins[pluginName]?.inputMiddleWare

( + // styledObj, + // true, + // true, + // Component + // ); + // } + + // theme = styledObj; + + // move inside stylehash created + const sxConvertedObject = convertStyledToStyledVerbosed(theme); let StyledComponent = verboseStyled( @@ -1933,36 +2034,43 @@ export function styled( 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, - componentStyleConfig, - ExtendedConfig, - }); - } - } + StyledComponent.isAnimatedComponent = Component.isAnimatedComponent; - for (const pluginName in plugins) { - const compWrapper = - // @ts-ignore - typeof plugins[pluginName].wrapperComponentMiddleWare === 'function' - ? // @ts-ignore - plugins[pluginName].wrapperComponentMiddleWare() - : null; + // move before returning component from verboseStyled - if (compWrapper) { - for (const key of Object.keys(compWrapper)) { - // @ts-ignore - StyledComponent[key] = compWrapper[key]; - } - } - } + // @ts-ignore + // plugins?.reverse(); + // for (const pluginName in plugins) { + // // @ts-ignore + // if (plugins[pluginName]?.componentMiddleWare) { + // // @ts-ignore + // StyledComponent = plugins[pluginName]?.componentMiddleWare({ + // Component: StyledComponent, + // theme, + // componentStyleConfig, + // ExtendedConfig, + // }); + // } + // } + // move before returning component from verboseStyled + + // for (const pluginName in plugins) { + // const compWrapper = + // // @ts-ignore + // typeof plugins[pluginName].wrapperComponentMiddleWare === 'function' + // ? // @ts-ignore + // plugins[pluginName].wrapperComponentMiddleWare() + // : null; + + // if (compWrapper) { + // for (const key of Object.keys(compWrapper)) { + // // @ts-ignore + // StyledComponent[key] = compWrapper[key]; + // } + // } + // } return StyledComponent; } diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts index 72a55e834..47301963f 100644 --- a/packages/react/src/types.ts +++ b/packages/react/src/types.ts @@ -33,6 +33,29 @@ export type COLORMODES = 'dark' | 'light'; /*************************** CORE TYPES *************************************************/ +export interface IStyledPlugin { + config?: IStyled; + register(styledUtils: IStyled): void; + inputMiddleWare(styledObj: any): void; + componentMiddleWare?(props: any): void; +} +export interface IAnimationDriverPlugin { + config?: IStyled; + register(styledUtils: IStyled): void; + engine: any; +} + +export class IAnimationResolver { + aliases?: any; + tokens?: any; + ref?: any; +} +export class IStyled { + aliases?: any; + tokens?: any; + ref?: any; +} + export interface Tokens { colors?: { [key: GenericKey]: Record & {} }; sizes?: { [key: GenericKey]: Record & {} }; @@ -53,6 +76,7 @@ export type AliasesType = { [key: string]: keyof RNStyledProps; }; +export type GlobalPluginType = unknown; export type GenericAliases = {}; export type GenericGlobalStyle = { // variants: {}; @@ -78,19 +102,14 @@ export type ThemeStyles = Partial<{ export type GlueStackConfig< IToken extends Tokens, IGlobalAliases, - IGlobalStyle + IGlobalStyle, + PluginType = [] > = { tokens: IToken; aliases: IGlobalAliases; globalStyle?: GlobalStyles; - plugins?: Array; + plugins?: PluginType; themes?: ThemeStyles; - components?: { - [key: string]: { - theme: Partial>; - componentConfig?: IComponentStyleConfig; - }; - }; }; export type ComponentsThemeType = { @@ -102,12 +121,20 @@ export type ComponentsThemeType = { export type InferConfig = Conf extends GlueStackConfig< infer A, infer C, - infer D + infer D, + infer B > - ? GlueStackConfig + ? GlueStackConfig : any; export type CreateGenericConfig = GlueStackConfig< + Tokens, + GenericAliases, + GenericGlobalStyle, + GlobalPluginType +>; + +export type CreateGenericComponents = GlueStackConfig< Tokens, GenericAliases, GenericGlobalStyle @@ -115,22 +142,32 @@ export type CreateGenericConfig = GlueStackConfig< // All Aliases export type Aliases = GSConfig['aliases']; +export type Plugins = GSConfig['plugins']; export type Components = GSConfig['components']; export type IMediaQueries = keyof GSConfig['tokens']['mediaQueries']; export type SxStyleProps< GenericComponentStyles, Variants, - GenericComponentProps + GenericComponentProps, + PluginType > = { sx?: Partial< - SxProps & { + SxProps< + GenericComponentStyles, + Variants, + GenericComponentProps, + '', + '', + PluginType + > & { [Key in `@${IMediaQueries}`]?: SxProps< GenericComponentStyles, Variants, GenericComponentProps, '', - Key + Key, + PluginType >; } >; @@ -139,14 +176,12 @@ export type SxStyleProps< //@ts-ignore type GlobalVariants = GSConfig['globalStyle']['variants']; -export type IComponentStyleConfig = Partial< - { - descendantStyle: any; - ancestorStyle: any; - resolveProps: any; - componentName: ComCon; - } & { [key: string]: any } ->; +export type IComponentStyleConfig = Partial<{ + descendantStyle: any; + ancestorStyle: any; + resolveProps: any; + componentName: ComCon; +}>; export type Config = { alias: { [K: string]: any }; @@ -164,10 +199,10 @@ type PropsResolveType = { props?: Partial; }; type PropertyResolverType = PropsResolveType & ResolverType; -export type ExtendedConfigType = { +export type ExtendedConfigType = { propertyTokenMap?: PropertyTokenMapType; propertyResolver?: PropertyResolverType; - plugins?: T; + plugins?: Array; }; /*********************** GLOBAL STYLE TYPES ****************************************/ @@ -263,33 +298,45 @@ export type GlobalStyles = GlobalVariantSx< /*********************** USER THEME / SX TYPES ****************************************/ export type ITheme = Partial< - //@ts-ignore - StyledThemeProps + StyledThemeProps< + Variants, + 'style' extends keyof P ? P['style'] : {}, + P, + 'animationComponentGluestack' extends keyof P + ? P['animationComponentGluestack'] extends true + ? Plugins + : [] + : [] + > >; export type StyledThemeProps< Variants, GenericComponentStyles, - GenericComponentProps + GenericComponentProps, + PluginTypes > = SxProps< GenericComponentStyles, Variants & GlobalVariants, GenericComponentProps, '', - '' + '', + PluginTypes > & { [Key in `@${IMediaQueries}`]: SxProps< GenericComponentStyles, Variants, GenericComponentProps, '', - Key + Key, + PluginTypes >; } & { variants: VariantType< Variants, GenericComponentStyles, - GenericComponentProps + GenericComponentProps, + PluginTypes >; // sizes?: SizeTypeNew; compoundVariants?: Array< @@ -297,10 +344,20 @@ export type StyledThemeProps< >; defaultProps?: { [Key in keyof MergeNested< - VariantType, + VariantType< + Variants, + GenericComponentStyles, + GenericComponentProps, + PluginTypes + >, GlobalVariants >]?: keyof MergeNested< - VariantType, + VariantType< + Variants, + GenericComponentStyles, + GenericComponentProps, + PluginTypes + >, GlobalVariants >[Key]; } & { [key: string]: any }; @@ -315,7 +372,8 @@ type PassingPropsType< GenericComponentStyles, Variants, GenericComponentProps, - MediaQuery + MediaQuery, + PluginType > = MediaQuery extends '' ? { props?: Partial< @@ -328,7 +386,8 @@ type PassingPropsType< VariantType< Variants, GenericComponentStyles, - GenericComponentProps + GenericComponentProps, + PluginType >, GlobalVariants >]?: @@ -336,7 +395,8 @@ type PassingPropsType< VariantType< Variants, GenericComponentStyles, - GenericComponentProps + GenericComponentProps, + PluginType >, GlobalVariants >[Key]; @@ -345,13 +405,22 @@ type PassingPropsType< } : {}; -// PluginPropsType< -// PluginType, -// GenericComponentProps, -// GenericComponentStyles, -// PLATFORM -// > - +type AnimatedPropsType = { + opacity: number | string; + x: number | string | {}; + y: number | string | {}; + scale: any; + scaleX: any; + scaleY: any; + skewX: any; + skewY: any; + perspective: any; + rotate: number; + rotateY: number; + rotateZ: number; + matrix: any; +}; +// componentDriver // eslint-disable-next-line @typescript-eslint/no-unused-vars type PluginPropsType< PluginType, @@ -362,26 +431,9 @@ type PluginPropsType< [key in keyof UnionToIntersection< // @ts-ignore ReturnType - >]: Partial< - UnionToIntersection< - // @ts-ignore - ReturnType - >[key] extends keyof GenericComponentProps - ? StylePropsType & - GenericComponentProps[UnionToIntersection< - // @ts-ignore - ReturnType - >[key]] - : UnionToIntersection< - // @ts-ignore - ReturnType - >[key] extends keyof GenericComponentStyles - ? GenericComponentStyles[UnionToIntersection< - // @ts-ignore - ReturnType - >[key]] - : any - >; + >]: Partial & + Partial> & + Partial; }; export type SxProps< @@ -389,82 +441,108 @@ export type SxProps< Variants = unknown, GenericComponentProps = unknown, PLATFORM = '', - MediaQuery = '' -> = Partial< - StylePropsType & - PassingPropsType< - GenericComponentStyles, - Variants, - GenericComponentProps, - MediaQuery + MediaQuery = '', + PluginType = [] +> = + | Partial< + StylePropsType & + PassingPropsType< + GenericComponentStyles, + Variants, + GenericComponentProps, + MediaQuery, + PluginType + > > -> & { - [Key in `_${COLORMODES}`]?: SxProps< - GenericComponentStyles, - Variants, - GenericComponentProps, - PLATFORM, - MediaQuery - >; -} & { - [Key in `:${IState}`]?: SxProps< - GenericComponentStyles, - Variants, - GenericComponentProps, - PLATFORM, - MediaQuery - >; -} & { - [Key in `_${PLATFORMS}`]?: SxProps< - GenericComponentStyles, - Variants, - GenericComponentProps, - Key, - MediaQuery - > & - PassingPropsType< - GenericComponentStyles, - Variants, - GenericComponentProps, - MediaQuery - > & - Partial<{ - [key: string]: any; - }>; -} & { - [Key in `_${string}`]?: SxProps< - RNStyledProps, - {}, - GenericComponentProps, - PLATFORM, - MediaQuery - > & - PassingPropsType< - GenericComponentStyles, - {}, - GenericComponentProps, - MediaQuery - > & - Partial<{ - [key: string]: any; - }>; -}; + | (Partial< + PluginPropsType< + PluginType, + GenericComponentProps, + GenericComponentStyles, + PLATFORM + > + > & { + [Key in `_${COLORMODES}`]?: SxProps< + GenericComponentStyles, + Variants, + GenericComponentProps, + PLATFORM, + MediaQuery, + PluginType + >; + } & { + [Key in `:${IState}`]?: SxProps< + GenericComponentStyles, + Variants, + GenericComponentProps, + PLATFORM, + MediaQuery, + PluginType + >; + } & { + [Key in `_${PLATFORMS}`]?: SxProps< + GenericComponentStyles, + Variants, + GenericComponentProps, + Key, + MediaQuery, + PluginType + > & + PassingPropsType< + GenericComponentStyles, + Variants, + GenericComponentProps, + MediaQuery, + PluginType + > & + Partial<{ + [key: string]: any; + }>; + } & { + [Key in `_${string}`]?: SxProps< + RNStyledProps, + {}, + GenericComponentProps, + PLATFORM, + MediaQuery, + PluginType + > & + PassingPropsType< + GenericComponentStyles, + {}, + GenericComponentProps, + MediaQuery, + PluginType + > & + Partial<{ + [key: string]: any; + }>; + }); export type VariantType< Variants, GenericComponentStyles, - GenericComponentProps + GenericComponentProps, + PluginTypes > = | { [Key1 in keyof Variants]: { [Key in keyof Variants[Key1]]: Partial< - SxProps & { + SxProps< + GenericComponentStyles, + Variants, + GenericComponentProps, + '', + '', + PluginTypes + > & { [K in `@${IMediaQueries}`]?: SxProps< GenericComponentStyles, Variants, GenericComponentProps, '', - K + K, + PluginTypes >; } >; @@ -650,14 +728,32 @@ export type StyleIds = { export interface ICustomConfig {} +export interface ICustomComponents {} + export interface GSConfig extends Omit, - ICustomConfig {} + ICustomConfig, + GenericComponents { + components: ICustomComponents; +} + +interface GenericComponents { + components: {}; +} /********************* COMPONENT PROPS TYPE *****************************************/ export type ComponentProps = - SxStyleProps & { + SxStyleProps< + GenericComponentStyles, + Variants, + P, + 'animationComponentGluestack' extends keyof P + ? P['animationComponentGluestack'] extends true + ? Plugins + : [] + : [] + > & { states?: { [K in IState]?: boolean; }; @@ -760,9 +856,9 @@ export type RNStyles = TokenizedRNStyleProps< > >; -type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ( - k: infer I -) => void +export type UnionToIntersection = ( + U extends any ? (k: U) => void : never +) extends (k: infer I) => void ? I : never; @@ -848,3 +944,20 @@ export type GlobalStyleMap = Map< }>; }> >; + +export type ExtendedTheme = ITheme< + Variants, + ViewProps | ImageProps | TextProps +>; + +// export type CreateStyle = { +// theme: Component & +// ITheme; +// componentConfig?: Omit; +// }; + +export type CreateComponents = { + [key in keyof T]: T[key]; +}; + +export type StyledConfig = any; diff --git a/packages/react/src/updateOrderUnResolvedMap.ts b/packages/react/src/updateOrderUnResolvedMap.ts index 97ccfbb9d..d271f8dfe 100644 --- a/packages/react/src/updateOrderUnResolvedMap.ts +++ b/packages/react/src/updateOrderUnResolvedMap.ts @@ -21,7 +21,10 @@ export function updateOrderUnResolvedMap( platform: string = '' ) { const prefixClassName = declarationType === 'inline' ? 'gs' : ''; - const shouldGuessDescendants = declarationType === 'inline' ? true : false; + const shouldGuessDescendants = + declarationType === 'inline' || declarationType === 'extended' + ? true + : false; const unresolvedTheme = styledToStyledResolved(theme, [], {}, false); const orderedUnResolvedTheme = styledResolvedToOrderedSXResolved(unresolvedTheme); diff --git a/tsconfig.json b/tsconfig.json index ff3872542..df72c6d12 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,6 @@ "allowUnreachableCode": false, "allowUnusedLabels": true, "esModuleInterop": true, - "importsNotUsedAsValues": "error", "forceConsistentCasingInFileNames": true, "jsx": "react", "lib": ["esnext", "dom"], diff --git a/yarn.lock b/yarn.lock index f186a0857..5a435166e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -187,6 +187,21 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" + integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" @@ -226,6 +241,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-function-name@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" @@ -241,6 +261,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-member-expression-to-functions@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz#b95a144896f6d491ca7863576f820f3628818621" + integrity sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-member-expression-to-functions@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" @@ -255,6 +282,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9", "@babel/helper-module-transforms@^7.9.0": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" @@ -266,6 +300,17 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" +"@babel/helper-module-transforms@^7.22.15": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.20.tgz#da9edc14794babbe7386df438f3768067132f59e" + integrity sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-optimise-call-expression@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" @@ -327,11 +372,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + "@babel/helper-validator-option@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" @@ -879,6 +934,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" +"@babel/plugin-transform-modules-commonjs@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz#b11810117ed4ee7691b29bd29fd9f3f98276034f" + integrity sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg== + dependencies: + "@babel/helper-module-transforms" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/plugin-transform-modules-systemjs@^7.22.5": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz#3386be5875d316493b517207e8f1931d93154bb1" @@ -928,6 +992,13 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-transform-object-assign@^7.16.7": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.22.5.tgz#290c1b9555dcea48bb2c29ad94237777600d04f9" + integrity sha512-iDhx9ARkXq4vhZ2CYOSnQXkmxkDgosLi3J8Z17mKz7LyzthtkdVchLD7WZ3aXeCuvJDOW3+1I5TpJmwIbF9MKQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-object-rest-spread@^7.22.5": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.11.tgz#dbbb06ce783cd994a8f430d8cefa553e9b42ca62" @@ -1116,6 +1187,16 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-typescript" "^7.22.5" +"@babel/plugin-transform-typescript@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" + integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" + "@babel/plugin-transform-unicode-escapes@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" @@ -1274,6 +1355,17 @@ "@babel/plugin-transform-modules-commonjs" "^7.22.11" "@babel/plugin-transform-typescript" "^7.22.11" +"@babel/preset-typescript@^7.16.7": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.22.15.tgz#43db30516fae1d417d748105a0bc95f637239d48" + integrity sha512-HblhNmh6yM+cU4VwbBRpxFhxsTdfS1zsvH9W+gEjD0ARV9+8B4sNfpI6GuhePti84nuvhiwKS539jKPFHskA9A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.15" + "@babel/plugin-transform-typescript" "^7.22.15" + "@babel/register@^7.12.1", "@babel/register@^7.13.16": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939" @@ -1347,6 +1439,15 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15": + version "7.22.19" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.19.tgz#7425343253556916e440e662bb221a93ddb75684" + integrity sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.19" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -1743,6 +1844,13 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== +"@egjs/hammerjs@^2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124" + integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A== + dependencies: + "@types/hammerjs" "^2.0.36" + "@emotion/babel-plugin@^11.11.0": version "11.11.0" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" @@ -1812,6 +1920,13 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + "@emotion/is-prop-valid@^1.1.0", "@emotion/is-prop-valid@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" @@ -2464,6 +2579,13 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@gluestack-style/animation-plugin@^0.1.7": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@gluestack-style/animation-plugin/-/animation-plugin-0.1.12.tgz#887b57097397817c31fef25c8c53af381c11633e" + integrity sha512-lkj8iY5JBnhroUkP5gWE1zEpocb5GAK/G9SxL8DdWYQrsWOFpXr/mF/K67Dbxiv/n4B9BVff7sNTAddju+4UAw== + dependencies: + "@legendapp/motion" "^2.2.0" + "@gluestack-style/animation-plugin@latest": version "0.1.7" resolved "https://registry.yarnpkg.com/@gluestack-style/animation-plugin/-/animation-plugin-0.1.7.tgz#c9feae42684a48f2b5ece932681837d4b3ce7104" @@ -2497,7 +2619,7 @@ "@babel/traverse" "^7.20.5" lodash.merge "^4.6.2" -"@gluestack-style/react@^0.1.11", "@gluestack-style/react@^0.1.33": +"@gluestack-style/react@^0.1.33": version "0.1.33" resolved "https://registry.yarnpkg.com/@gluestack-style/react/-/react-0.1.33.tgz#cd18f38bf359527e4f79d223bb07e9024f40ba4f" integrity sha512-wBdoOA3i/cp0EcgJnwJgL1a8BATjbX/pCZgWm31N6sZOgCB4Phq7m0bDjfSpeJ8sKpOEDlUP5wYCo7Yww0mbqA== @@ -2505,6 +2627,14 @@ inline-style-prefixer "^6.0.1" normalize-css-color "^1.0.2" +"@gluestack-style/react@^0.2.11-alpha.0", "@gluestack-style/react@^0.2.16", "@gluestack-style/react@^0.2.21", "@gluestack-style/react@^0.2.49": + version "0.2.51" + resolved "https://registry.yarnpkg.com/@gluestack-style/react/-/react-0.2.51.tgz#0cfcca4f97f908ed3a352bd7e2336d436cc22415" + integrity sha512-21TLr+e7KneP8N1d1iMKG6npMdYb/oPN/t5KZ/2kns2mg9NVCrfVmVuuMYKo+Xcej95BFOHuGuomskzLwdK1HQ== + dependencies: + inline-style-prefixer "^6.0.1" + normalize-css-color "^1.0.2" + "@gluestack-ui/actionsheet@^0.2.16", "@gluestack-ui/actionsheet@^0.2.7", "@gluestack-ui/actionsheet@latest": version "0.2.16" resolved "https://registry.yarnpkg.com/@gluestack-ui/actionsheet/-/actionsheet-0.2.16.tgz#052a733966c517450a3cd6f832932ccf77924867" @@ -3423,6 +3553,59 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== +"@motionone/animation@^10.12.0": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807" + integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ== + dependencies: + "@motionone/easing" "^10.15.1" + "@motionone/types" "^10.15.1" + "@motionone/utils" "^10.15.1" + tslib "^2.3.1" + +"@motionone/dom@10.12.0": + version "10.12.0" + resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed" + integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw== + dependencies: + "@motionone/animation" "^10.12.0" + "@motionone/generators" "^10.12.0" + "@motionone/types" "^10.12.0" + "@motionone/utils" "^10.12.0" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/easing@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.15.1.tgz#95cf3adaef34da6deebb83940d8143ede3deb693" + integrity sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw== + dependencies: + "@motionone/utils" "^10.15.1" + tslib "^2.3.1" + +"@motionone/generators@^10.12.0": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c" + integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ== + dependencies: + "@motionone/types" "^10.15.1" + "@motionone/utils" "^10.15.1" + tslib "^2.3.1" + +"@motionone/types@^10.12.0", "@motionone/types@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb" + integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA== + +"@motionone/utils@^10.12.0", "@motionone/utils@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438" + integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw== + dependencies: + "@motionone/types" "^10.15.1" + hey-listen "^1.0.8" + tslib "^2.3.1" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -6060,6 +6243,11 @@ dependencies: "@types/node" "*" +"@types/hammerjs@^2.0.36": + version "2.0.42" + resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.42.tgz#d7a53edbc51b2c13a9a759c45d7b5e61243d7dba" + integrity sha512-Xxk14BrwHnGi0xlURPRb+Y0UNn2w3cTkeFm7pKMsYOaNgH/kabbJLhcBoNIodwsbTz7Z8KcWjtDvlGH0nc0U9w== + "@types/hast@^2.0.0": version "2.3.5" resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.5.tgz#08caac88b44d0fdd04dc17a19142355f43bd8a7a" @@ -6085,6 +6273,11 @@ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== +"@types/invariant@^2.2.35": + version "2.2.35" + resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" + integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== + "@types/is-ci@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/is-ci/-/is-ci-3.0.0.tgz#7e8910af6857601315592436f030aaa3ed9783c3" @@ -11643,6 +11836,27 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +framer-motion@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" + integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw== + dependencies: + "@motionone/dom" "10.12.0" + framesync "6.0.1" + hey-listen "^1.0.8" + popmotion "11.0.3" + style-value-types "5.0.0" + tslib "^2.1.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +framesync@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20" + integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA== + dependencies: + tslib "^2.1.0" + freeport-async@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/freeport-async/-/freeport-async-2.0.0.tgz#6adf2ec0c629d11abff92836acd04b399135bab4" @@ -12427,6 +12641,11 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -15871,6 +16090,13 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +moti@^0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/moti/-/moti-0.26.0.tgz#863e70e61c9d597f4fd701e588f41963335b927f" + integrity sha512-430HDIwhPQi/DkMvocyAZGkAX3ibmbyF3Fj23GuhbTB+RUXYTOnbsvygr89ABJjllYuxx4Xjd2Z4Qab0Su5mcg== + dependencies: + framer-motion "^6.5.1" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -17187,6 +17413,16 @@ polished@^4.2.2: dependencies: "@babel/runtime" "^7.17.8" +popmotion@11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9" + integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA== + dependencies: + framesync "6.0.1" + hey-listen "^1.0.8" + style-value-types "5.0.0" + tslib "^2.1.0" + portfinder@^1.0.26: version "1.0.32" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" @@ -18145,6 +18381,17 @@ react-native-codegen@^0.70.6: jscodeshift "^0.13.1" nullthrows "^1.1.1" +react-native-gesture-handler@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.13.1.tgz#bad89caacd62c4560b9953b02f85f37ee42d5d4c" + integrity sha512-hW454X7sjuiBN+lobqw63pmT3boAmTl5OP6zQLq83iEe4T6PcHZ9lxzgCrebtgmutY8cJfq9rM2dOUVh9WBcww== + dependencies: + "@egjs/hammerjs" "^2.0.17" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + lodash "^4.17.21" + prop-types "^15.7.2" + react-native-gradle-plugin@^0.70.3: version "0.70.3" resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8" @@ -18164,6 +18411,19 @@ react-native-modal-selector@^2.1.1: dependencies: prop-types "^15.5.10" +react-native-reanimated@~2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.12.0.tgz#5821eecfb1769b1617a67a2d4dec12fdeedb2b6e" + integrity sha512-nrlPyw+Hx9u4iJhZk9PoTvDo/QmVAd+bo7OK9Tv3hveNEF9++5oig/g3Uv9V93shy9avTYGsUprUvAEt/xdzeQ== + dependencies: + "@babel/plugin-transform-object-assign" "^7.16.7" + "@babel/preset-typescript" "^7.16.7" + "@types/invariant" "^2.2.35" + invariant "^2.2.4" + lodash.isequal "^4.5.0" + setimmediate "^1.0.5" + string-hash-64 "^1.0.3" + react-native-safe-area-context@4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz#239c60b8a9a80eac70a38a822b04c0f1d15ffc01" @@ -19825,6 +20085,11 @@ string-argv@0.3.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== +string-hash-64@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322" + integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw== + string-hash@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" @@ -20062,6 +20327,14 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" +style-value-types@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad" + integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA== + dependencies: + hey-listen "^1.0.8" + tslib "^2.1.0" + styled-components@^5.3.0: version "5.3.11" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.11.tgz#9fda7bf1108e39bf3f3e612fcc18170dedcd57a8" @@ -20685,7 +20958,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==