From 7a49841f2eda505a66e2b2b9508cdd48afd8c607 Mon Sep 17 00:00:00 2001 From: ankit-tailor Date: Wed, 6 Sep 2023 12:55:45 +0530 Subject: [PATCH 1/4] fix: perf improvments --- packages/react/package.json | 2 +- .../injectComponentAndDescendantStyles.ts | 7 +- packages/react/src/style-sheet/index.ts | 3 +- packages/react/src/styled.tsx | 408 ++++++++---------- yarn.lock | 21 + 5 files changed, 212 insertions(+), 229 deletions(-) diff --git a/packages/react/package.json b/packages/react/package.json index a6d318d7b..bce29cb11 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.22", + "version": "0.2.23-alpha.7", "keywords": [ "React Native", "Next.js", diff --git a/packages/react/src/resolver/injectComponentAndDescendantStyles.ts b/packages/react/src/resolver/injectComponentAndDescendantStyles.ts index ead2329a0..913ac2f71 100644 --- a/packages/react/src/resolver/injectComponentAndDescendantStyles.ts +++ b/packages/react/src/resolver/injectComponentAndDescendantStyles.ts @@ -11,7 +11,8 @@ export function injectComponentAndDescendantStyles( orderedResolved: OrderedSXResolved, styleTagId?: string, type: 'boot' | 'inline' = 'boot', - _GluestackStyleSheet: StyleInjector = GluestackStyleSheet + _GluestackStyleSheet: StyleInjector = GluestackStyleSheet, + platform: string = '' ) { const [ componentOrderResolvedBaseStyle, @@ -82,7 +83,9 @@ export function injectComponentAndDescendantStyles( false ); - GluestackStyleSheet.inject(toBeInjected); + if (platform === 'web') { + GluestackStyleSheet.inject(toBeInjected); + } return styleCSSIdsArr; } diff --git a/packages/react/src/style-sheet/index.ts b/packages/react/src/style-sheet/index.ts index 3dee85272..4a8805dc8 100644 --- a/packages/react/src/style-sheet/index.ts +++ b/packages/react/src/style-sheet/index.ts @@ -109,7 +109,7 @@ export class StyleInjector { return toBeInjected; } - inject(toBeInjected: any) { + inject(toBeInjected: any = {}) { Object.keys(toBeInjected).forEach((type) => { Object.keys(toBeInjected[type]).forEach((styleTag) => { this.injectStyles(toBeInjected[type][styleTag], type, styleTag); @@ -130,6 +130,7 @@ export class StyleInjector { theme, componentExtendedConfig ); + // addThemeConditionInMeta(componentTheme, CONFIG); // delete componentTheme.meta.cssRuleset; diff --git a/packages/react/src/styled.tsx b/packages/react/src/styled.tsx index 402536b04..74f02de9f 100644 --- a/packages/react/src/styled.tsx +++ b/packages/react/src/styled.tsx @@ -1,6 +1,4 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable react-hooks/exhaustive-deps */ -/* eslint-disable no-console */ import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'; import type { @@ -20,11 +18,9 @@ import { resolveStringToken, shallowMerge, deepMergeArray, - addThemeConditionInMeta, } from './utils'; import { convertUtilityPropsToSX } from './core/convert-utility-to-sx'; import { useStyled } from './StyledProvider'; -// import { useTheme } from './Theme'; import { propertyTokenMap } from './propertyTokenMap'; import { Platform, StyleSheet } from 'react-native'; import { INTERNAL_updateCSSStyleInOrderedResolved } from './updateCSSStyleInOrderedResolved'; @@ -110,46 +106,33 @@ function convertUtiltiyToSXFromProps( function getStateStyleCSSFromStyleIdsAndProps( flatternStyleIdObject: any, - states: any, - colorMode: any + currentStateArray: any ) { const stateStyleCSSIds: Array = []; let props = {}; - let stateColorMode: any = {}; - if (colorMode || states) { - stateColorMode = { - ...states, - [colorMode]: true, - }; - - Object.keys(flatternStyleIdObject).forEach((styleId) => { - const styleIdKeyArray = styleId.split('.'); - - const filteredStyleIdKeyArray = styleIdKeyArray.filter( - (item) => item !== 'colorMode' && item !== 'state' && item !== 'props' - ); + Object.keys(flatternStyleIdObject).forEach((styleId) => { + const styleIdKeyArray = styleId.split('.'); - const currentStateArray = Object.keys(stateColorMode).filter( - (key) => stateColorMode[key] === true - ); + const filteredStyleIdKeyArray = styleIdKeyArray.filter( + (item) => item !== 'colorMode' && item !== 'state' && item !== 'props' + ); - if (styleId.includes('ids')) { - // if (type === 'inline' && ) { - // stateStyleCSSIds.push(...flatternStyleIdObject[styleId]); - // } - } else if ( - styleId.includes('props') && - isSubset(filteredStyleIdKeyArray, currentStateArray) - ) { - props = deepMergeObjects(props, flatternStyleIdObject[styleId]); - } else { - if (isSubset(filteredStyleIdKeyArray, currentStateArray)) { - stateStyleCSSIds.push(...flatternStyleIdObject[styleId]); - } + if (styleId.includes('ids')) { + // if (type === 'inline' && ) { + // stateStyleCSSIds.push(...flatternStyleIdObject[styleId]); + // } + } else if ( + styleId.includes('props') && + isSubset(filteredStyleIdKeyArray, currentStateArray) + ) { + props = deepMergeObjects(props, flatternStyleIdObject[styleId]); + } else { + if (isSubset(filteredStyleIdKeyArray, currentStateArray)) { + stateStyleCSSIds.push(...flatternStyleIdObject[styleId]); } - }); - } + } + }); return { cssIds: stateStyleCSSIds, passingProps: props }; } @@ -215,7 +198,11 @@ function getMergedDefaultCSSIdsAndProps( baseStyleCSSIds.push(...componentStyleIds?.baseStyle?.ids); props = deepMergeObjects(props, componentStyleIds?.baseStyle?.props); } - let passingVariantProps = getVariantProps(props, theme).variantProps; + let passingVariantProps = {}; + + // if (props) { + passingVariantProps = getVariantProps(props, theme).variantProps; + // } const mergedVariantProps = shallowMerge( { ...passingVariantProps }, @@ -388,6 +375,24 @@ function setStateAndColorModeCssIdsAndProps( componentDescendantStyleIds: any, sxDescendantStyleIds: any ) { + if (!componentStyleIds) { + return { + baseStyleCSSIds: [], + variantStyleCSSIds: [], + passingProps: {}, + }; + } + let stateColorMode: any = {}; + let currentStateArray: any = []; + if (colorMode || states) { + stateColorMode = { + ...states, + [colorMode]: true, + }; + currentStateArray = Object.keys(stateColorMode).filter( + (key) => stateColorMode[key] === true + ); + } const { baseStyleCSSIds: mergedBaseStyleCSSIds, variantStyleCSSIds: mergedVariantStyleCSSIds, @@ -401,11 +406,10 @@ function setStateAndColorModeCssIdsAndProps( colorMode, theme, componentVariantFlatternStyleIdObject, - componentCompoundVariantFlatternStyleIdObject + componentCompoundVariantFlatternStyleIdObject, + currentStateArray ); - // console.log(componentCompoundVariantFlatternStyleIdObject, '>>>>>>>'); - // for sx props const { baseStyleCSSIds: mergedSXBaseStyleCSSIds, @@ -420,16 +424,17 @@ function setStateAndColorModeCssIdsAndProps( colorMode, theme, sxVariantFlatternStyleObject, - sxCompoundVariantFlatternStyleObject + sxCompoundVariantFlatternStyleObject, + currentStateArray ); - // // for descendants + // for descendants const mergedDescendantsStyle: any = {}; - // componentBaseStyleFlatternStyleIdObject - // componentVariantFlatternStyleIdObject - // componentCompoundVariantFlatternStyleIdObject - if (componentDescendantStyleIds) { + if ( + componentDescendantStyleIds && + Object.keys(componentDescendantStyleIds).length > 0 + ) { Object.keys(componentDescendantStyleIds).forEach((key) => { const { baseStyleCSSIds: descendantBaseStyleCSSIds, @@ -450,7 +455,8 @@ function setStateAndColorModeCssIdsAndProps( ], componentDescendantFlattenStyleObject[key]?.[ 'componentCompoundVariantFlatternStyleIdObject' - ] + ], + currentStateArray ); mergedDescendantsStyle[key] = { baseStyleCSSIds: descendantBaseStyleCSSIds, @@ -460,9 +466,12 @@ function setStateAndColorModeCssIdsAndProps( }); } - // // for sx descendants + // for sx descendants const mergedSxDescendantsStyle: any = {}; - if (sxDescendantStyleIds.current) { + if ( + sxDescendantStyleIds.current && + Object.keys(sxDescendantStyleIds.current).length > 0 + ) { Object.keys(sxDescendantStyleIds.current).forEach((key) => { const { baseStyleCSSIds: sxDescendantBaseStyleCSSIds, @@ -483,7 +492,8 @@ function setStateAndColorModeCssIdsAndProps( ], sxDescendantFlattenStyleObject[key]?.[ 'componentCompoundVariantFlatternStyleIdObject' - ] + ], + currentStateArray ); mergedSxDescendantsStyle[key] = { @@ -509,12 +519,13 @@ function setStateAndColorModeCssIdsAndProps( function getMergedStateAndColorModeCSSIdsAndProps( componentStyleIds: any, componentBaseStyleFlatternStyleIdObject: any, - states: any, + _states: any, incomingVariantProps: any, - COLOR_MODE: 'light' | 'dark', + _COLOR_MODE: 'light' | 'dark', theme: any, componentVariantFlatternStyleIdObject: any, - componentCompoundVariantFlatternStyleIdObject: any + componentCompoundVariantFlatternStyleIdObject: any, + currentStateArray: any ) { if (!componentStyleIds) { return { @@ -532,8 +543,7 @@ function getMergedStateAndColorModeCSSIdsAndProps( const { cssIds: stateStleCSSFromStyleIds, passingProps: stateStyleProps } = getStateStyleCSSFromStyleIdsAndProps( componentBaseStyleFlatternStyleIdObject, - states, - COLOR_MODE + currentStateArray ); push_unique(stateBaseStyleCSSIds, stateStleCSSFromStyleIds); @@ -561,12 +571,10 @@ function getMergedStateAndColorModeCSSIdsAndProps( passingProps: stateStyleProps, } = getStateStyleCSSFromStyleIdsAndProps( componentVariantFlatternStyleIdObject[variantObjectPath], - states, - COLOR_MODE + currentStateArray ); push_unique(stateVariantStyleCSSIds, stateStleCSSFromStyleIds); - // stateVariantStyleCSSIds.push(...stateStleCSSFromStyleIds); props = deepMergeObjects(props, stateStyleProps); } @@ -583,14 +591,11 @@ function getMergedStateAndColorModeCSSIdsAndProps( cssIds: stateStleCSSFromStyleIds, passingProps: stateStyleProps, } = getStateStyleCSSFromStyleIdsAndProps( - //@ts-ignore componentCompoundVariantFlatternStyleIdObject[index], - states, - COLOR_MODE + currentStateArray ); push_unique(stateVariantStyleCSSIds, stateStleCSSFromStyleIds); - // stateVariantStyleCSSIds.push(...stateStleCSSFromStyleIds); props = deepMergeObjects(props, stateStyleProps); } @@ -606,8 +611,6 @@ function getMergedStateAndColorModeCSSIdsAndProps( } function getAncestorCSSStyleIds(compConfig: any, context: any) { - // console.setStartTimeStamp('getAncestorCSSStyleIds'); - let ancestorBaseStyleIds: any[] = []; let ancestorVariantStyleIds: any[] = []; let ancestorPassingProps: any = {}; @@ -623,7 +626,6 @@ function getAncestorCSSStyleIds(compConfig: any, context: any) { }); } } - // console.setEndTimeStamp('getAncestorCSSStyleIds'); return { baseStyleCSSIds: ancestorBaseStyleIds, @@ -633,8 +635,6 @@ function getAncestorCSSStyleIds(compConfig: any, context: any) { } function mergeArraysInObjects(...objects: any) { - // console.setStartTimeStamp('mergeArraysInObjects'); - const merged: any = {}; for (const object of objects) { @@ -655,19 +655,11 @@ function mergeArraysInObjects(...objects: any) { ); }); } - // console.setEndTimeStamp('mergeArraysInObjects'); return merged; } -// let resolvedComponentMap = new Map(); - -// function isAlreadyResolved(Component) { - -// } function resolvePlatformTheme(theme: any, platform: any) { - // console.setStartTimeStamp('resolvePlatformTheme', 'boot'); - if (typeof theme === 'object') { Object.keys(theme).forEach((themeKey) => { if (themeKey !== 'style' && themeKey !== 'defaultProps') { @@ -691,7 +683,6 @@ function resolvePlatformTheme(theme: any, platform: any) { } }); } - // console.setEndTimeStamp('resolvePlatformTheme', 'boot'); } export function getVariantProps( @@ -699,8 +690,6 @@ export function getVariantProps( theme: any, shouldDeleteVariants: boolean = true ) { - // console.setStartTimeStamp('getVariantProps'); - const variantTypes = theme?.variants ? Object.keys(theme.variants) : []; const variantProps: any = {}; const restProps = { ...props }; @@ -724,36 +713,8 @@ export function getVariantProps( variantProps, restProps, }; - - // console.setEndTimeStamp('getVariantProps'); } -// const styledResolved = styledToStyledResolved(theme, [], CONFIG); -// const orderedResovled = styledResolvedToOrderedSXResolved(styledResolved); - -// INTERNAL_updateCSSStyleInOrderedResolved(orderedResovled); -// //set css ruleset -// globalOrderedList.push(...orderedResovled); - -// // StyleIds -// const componentStyleIds = getComponentStyleIds( -// orderedResovled.filter((item) => !item.meta.path?.includes('descendants')) -// ); - -// if (componentStyleConfig.DEBUG === 'INPUT') { -// // console.log(componentStyleIds, 'hello state here >>'); -// } - -// // Descendants -// const descendantStyleIds = getDescendantStyleIds( -// orderedResovled.filter((item) => item.meta.path?.includes('descendants')), -// componentStyleConfig.descendantStyle -// ); - -// - -// BASE COLOR MODE RESOLUTION - const getStyleIdsFromMap = ( CONFIG: any, ExtendedConfig: any, @@ -799,8 +760,6 @@ const getStyleIdsFromMap = ( return componentStyleObject; }; -// END BASE COLOR MODE RESOLUTION - export function verboseStyled( Component: React.ComponentType

, theme: Partial>, @@ -812,6 +771,7 @@ export function verboseStyled( component: StyleIds; descendant: StyleIds; }; + toBeInjected: any; styledIds: Array; } ) { @@ -822,10 +782,6 @@ export function verboseStyled( ...ExtendedConfig, }); - // const styledSystemProps = shallowMerge(CSSPropertiesMap, CONFIG?.aliases); - - // const originalThemeHash = stableHash(theme); - let declarationType: DeclarationType = 'boot'; if (Component.displayName === '__AsForwarder__') { @@ -834,22 +790,9 @@ export function verboseStyled( resolvePlatformTheme(theme, Platform.OS); - // @ts-ignore - const DEBUG_TAG = componentStyleConfig?.DEBUG; - const DEBUG = - process.env.NODE_ENV === 'development' && DEBUG_TAG ? false : false; - - if (DEBUG) { - console.group( - `%cVerboseStyled()`, - 'background: #4b5563; color: #d97706; font-weight: 700; padding: 2px 8px;' - ); - console.log( - `%c${DEBUG_TAG} verbosed theme`, - 'background: #4b5563; color: #16a34a; font-weight: 700; padding: 2px 8px;', - theme - ); - } + // const DEBUG_TAG = componentStyleConfig?.DEBUG; + // const DEBUG = + // process.env.NODE_ENV === 'development' && DEBUG_TAG ? false : false; //@ts-ignore type ITypeReactNativeStyles = P['style']; @@ -881,13 +824,6 @@ export function verboseStyled( orderedCSSIds = BUILD_TIME_PARAMS?.styledIds; GluestackStyleSheet.update(orderedResolved); - if (DEBUG) { - console.log( - `%cOrder resolved build time`, - 'background: #4b5563; color: #16a34a; font-weight: 700; padding: 2px 8px;', - orderedResolved - ); - } } else { const { styledIds: g, verbosedStyleIds } = updateOrderUnResolvedMap( theme, @@ -903,13 +839,6 @@ export function verboseStyled( if (BUILD_TIME_PARAMS?.verbosedStyleIds) { styleIds = BUILD_TIME_PARAMS?.verbosedStyleIds; - if (DEBUG) { - console.log( - `%cStyle Ids build time`, - 'background: #4b5563; color: #16a34a; font-weight: 700; padding: 2px 8px;', - styleIds - ); - } } function injectSx(sx: any, type: any = 'inline') { @@ -925,35 +854,6 @@ export function verboseStyled( componentExtendedConfig ); - // let componentTheme: any = - // // @ts-ignore - // sxStyledResolved.baseStyle.styledValueResolvedWithMeta; - - // sxStyledResolved.baseStyle.styledValueResolvedWithMeta = - // addThemeConditionInMeta(componentTheme, CONFIG); - - // const colorModeComponentThemes: any = sxStyledResolved.baseStyle?.colorMode; - // if (colorModeComponentThemes) { - // Object.keys(colorModeComponentThemes).forEach( - // (colorModeComponentTheme: any) => { - // if ( - // !colorModeComponentThemes[colorModeComponentTheme] - // .styledValueResolvedWithMeta?.meta.themeCondition - // ) { - // colorModeComponentThemes[ - // colorModeComponentTheme - // ].styledValueResolvedWithMeta.meta.themeCondition = {}; - // } - - // let componentTheme: any = - // colorModeComponentThemes[colorModeComponentTheme] - // .styledValueResolvedWithMeta; - - // addThemeConditionInMeta(componentTheme, CONFIG); - // } - // ); - // } - const sxHash = stableHash(sx); const orderedSXResolved = @@ -966,7 +866,13 @@ export function verboseStyled( 'gs' ); - injectComponentAndDescendantStyles(orderedSXResolved, sxHash, type); + injectComponentAndDescendantStyles( + orderedSXResolved, + sxHash, + type, + GluestackStyleSheet, + Platform.OS + ); return orderedSXResolved; } @@ -974,6 +880,8 @@ export function verboseStyled( // END BASE COLOR MODE RESOLUTION let CONFIG: any = {}; + let isInjected = false; + let sxStyleIds: any = {}; const containsDescendant = componentStyleConfig?.descendantStyle && @@ -988,11 +896,9 @@ export function verboseStyled( //@ts-ignore verbosedStyleIds: BUILD_TIME_VERBOSED_STYLE_IDS = {}, //@ts-ignore - styledIds: BUILD_TIME_STYLE_IDS = [], - //@ts-ignore toBeInjected: BUILD_TIME_toBeInjected = {}, - //@ts-ignore - sxHash: BUILD_TIME_sxHash = '', + // styledIds: BUILD_TIME_STYLE_IDS = [], + // sxHash: BUILD_TIME_sxHash = '', ...componentProps }: Omit & Partial> & @@ -1004,9 +910,10 @@ export function verboseStyled( ) => { const isClient = React.useRef(false); - //@ts-ignore + //@ts-ignore style: 222ms let themeDefaultProps = { ...theme.baseStyle?.props }; + // 240ms const sxComponentStyleIds = useRef({}); const sxDescendantStyleIds: any = useRef({}); @@ -1083,13 +990,26 @@ export function verboseStyled( orderedCSSIds = [...orderedCSSIds, ...globalStyleIds]; } - const toBeInjected = GluestackStyleSheet.resolve( - orderedCSSIds, - CONFIG, - componentExtendedConfig - ); + if ( + !BUILD_TIME_PARAMS || + !BUILD_TIME_PARAMS?.orderedResolved || + BUILD_TIME_PARAMS?.orderedResolved.length === 0 + ) { + const toBeInjected = GluestackStyleSheet.resolve( + orderedCSSIds, + CONFIG, + componentExtendedConfig + ); + if (Platform.OS === 'web') { + GluestackStyleSheet.inject(toBeInjected); + } + } else { + if (Platform.OS === 'web') { + //@ts-ignore + GluestackStyleSheet.inject(BUILD_TIME_PARAMS.toBeInjected); + } + } - GluestackStyleSheet.inject(toBeInjected); Object.assign(styledSystemProps, CONFIG?.aliases); const { @@ -1236,25 +1156,81 @@ export function verboseStyled( // FOR SX RESOLUTION let orderedComponentSXResolved: any = []; let orderedPassingSXResolved: any = []; - let sxStyleIds: any = {}; - const isInjected = useRef(false); - // if (BUILD_TIME_VERBOSED_STYLE_IDS) { - // sxStyleIds = BUILD_TIME_VERBOSED_STYLE_IDS; - // GluestackStyleSheet.update(BUILD_TIME_ORDERED_RESOLVED); - // GluestackStyleSheet.inject(BUILD_TIME_toBeInjected); - // } + if (BUILD_TIME_ORDERED_RESOLVED.length > 0 && !isClient.current) { + if (!isInjected) { + GluestackStyleSheet.update(BUILD_TIME_ORDERED_RESOLVED); + if (Platform.OS === 'web') { + GluestackStyleSheet.inject(BUILD_TIME_toBeInjected); + } + isInjected = true; + } + sxStyleIds = BUILD_TIME_VERBOSED_STYLE_IDS; + + if (!sxStyleIds.component) { + sxStyleIds.component = {}; + } + sxStyleIds.component.variants = componentStyleIds.variants; + //@ts-ignore + sxStyleIds.component.compoundVariants = + componentStyleIds.compoundVariants; + // console.setStartTimeStamp('setColorModeBaseStyleIds'); + sxComponentStyleIds.current = sxStyleIds?.component; + sxDescendantStyleIds.current = sxStyleIds.descendant; + // 315ms + // SX component style + //@ts-ignore + const { + baseStyleCSSIds: sxBaseStyleCSSIds, + variantStyleCSSIds: sxVariantStyleCSSIds, + passingProps: sxPassingProps, + } = getMergedDefaultCSSIdsAndProps( + //@ts-ignore + sxComponentStyleIds.current, + variantProps, + theme, + incomingComponentProps + ); + //@ts-ignore + // applySxStyleCSSIds.current = sxStyleCSSIds; + //@ts-ignore + applySxBaseStyleCSSIds.current = sxBaseStyleCSSIds; + //@ts-ignore + applySxVariantStyleCSSIds.current = sxVariantStyleCSSIds; + sxComponentPassingProps.current = sxPassingProps; + + const { + componentBaseStyleFlatternStyleIdObject: a, + componentVariantFlatternStyleIdObject: b, + componentCompoundVariantFlatternStyleIdObject: c, + } = getFlattenStyleObjectFromStyleIds(sxComponentStyleIds.current); + + if (sxDescendantStyleIds.current && containsDescendant) { + Object.keys(sxDescendantStyleIds.current).forEach( + (currentDescendant: any) => { + sxDescendantFlattenStyles[currentDescendant] = + getFlattenStyleObjectFromStyleIds( + sxDescendantStyleIds.current[currentDescendant] + ); + } + ); + } + + sxBaseStyleFlatternStyleObject = a; + sxVariantFlatternStyleObject = b; + sxCompoundVariantFlatternStyleObject = c; + } + if ( - BUILD_TIME_ORDERED_RESOLVED.length > 0 || Object.keys(filteredComponentSx).length > 0 || Object.keys(filteredPassingSx).length > 0 ) { function injectAndUpdateSXProps() { - if ( - Object.keys(filteredComponentSx).length > 0 || - Object.keys(filteredPassingSx).length > 0 - ) { + if (Object.keys(filteredComponentSx).length > 0) { orderedComponentSXResolved = injectSx(filteredComponentSx, 'inline'); + } + + if (Object.keys(filteredPassingSx).length > 0) { orderedPassingSXResolved = injectSx(filteredPassingSx, 'passing'); } @@ -1341,12 +1317,6 @@ export function verboseStyled( applyComponentInlineProps = applyComponentInlinePropsUpdated; } - if (BUILD_TIME_ORDERED_RESOLVED.length > 0 && !isInjected.current) { - GluestackStyleSheet.update(BUILD_TIME_ORDERED_RESOLVED); - GluestackStyleSheet.inject(BUILD_TIME_toBeInjected); - isInjected.current = true; - } - //// refactor end .... const { @@ -1355,7 +1325,7 @@ export function verboseStyled( componentCompoundVariantFlatternStyleIdObject: c, } = getFlattenStyleObjectFromStyleIds(sxComponentStyleIds.current); - if (sxDescendantStyleIds.current) { + if (sxDescendantStyleIds.current && containsDescendant) { Object.keys(sxDescendantStyleIds.current).forEach( (currentDescendant: any) => { sxDescendantFlattenStyles[currentDescendant] = @@ -1385,10 +1355,10 @@ export function verboseStyled( let mergedBaseStyleCSSIds: any = []; let mergedVariantStyleCSSIds: any = []; - let stateProps = []; + // let stateProps = []; let mergedSXBaseStyleCSSIds: any = []; let mergedSXVariantStyleCSSIds: any = []; - let mergedSxStateProps: any = []; + // let mergedSxStateProps: any = []; let mergedSxDescendantsStyle: any = {}; let mergedDescendantsStyle: any = {}; @@ -1397,10 +1367,10 @@ export function verboseStyled( const { mergedBaseStyleCSSIds: a, mergedVariantStyleCSSIds: b, - stateProps: c, + // stateProps: c, mergedSXBaseStyleCSSIds: d, mergedSXVariantStyleCSSIds: e, - mergedSxStateProps: f, + // mergedSxStateProps: f, mergedSxDescendantsStyle: g, mergedDescendantsStyle: h, } = setStateAndColorModeCssIdsAndProps( @@ -1424,10 +1394,10 @@ export function verboseStyled( mergedBaseStyleCSSIds = a; mergedVariantStyleCSSIds = b; - stateProps = c; + // stateProps = c; mergedSXBaseStyleCSSIds = d; mergedSXVariantStyleCSSIds = e; - mergedSxStateProps = f; + // mergedSxStateProps = f; mergedSxDescendantsStyle = g; // setComponentStatePassingProps(stateProps); // setSxStatePassingProps(mergedSxStateProps); @@ -1682,25 +1652,13 @@ export function styled( component: StyleIds; descendant: StyleIds; }; + toBeInjected: any; styledIds: Array; } ) { - // @ts-ignore - const DEBUG_TAG = componentStyleConfig?.DEBUG; - const DEBUG = - process.env.NODE_ENV === 'development' && DEBUG_TAG ? false : false; - - if (DEBUG) { - console.group( - `%cStyled()`, - 'background: #4b5563; color: #d97706; font-weight: 700; padding: 2px 8px;' - ); - console.log( - `%c${DEBUG_TAG} theme`, - 'background: #4b5563; color: #16a34a; font-weight: 700; padding: 2px 8px;', - theme - ); - } + // const DEBUG_TAG = componentStyleConfig?.DEBUG; + // const DEBUG = + // process.env.NODE_ENV === 'development' && DEBUG_TAG ? false : false; const sxConvertedObject = convertStyledToStyledVerbosed(theme); diff --git a/yarn.lock b/yarn.lock index 151cc02fd..6465e0121 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2485,6 +2485,27 @@ "@babel/traverse" "^7.20.5" lodash.merge "^4.6.2" +"@gluestack-style/babel-plugin-styled-resolver@^0.1.15-alpha.0": + version "0.1.15-alpha.0" + resolved "https://registry.yarnpkg.com/@gluestack-style/babel-plugin-styled-resolver/-/babel-plugin-styled-resolver-0.1.15-alpha.0.tgz#776e0ba60cbdaeefcd966b6708dd0408d4a57213" + integrity sha512-Q0dDTW8QroqOxo5ZP9Ebq0wAAlVl6dOlOchT1LZlanRc2GzvAf12GZrTGdzYQybYh6oVNmoIQZn6/3zL6qfsow== + dependencies: + "@babel/core" "^7.20.5" + "@babel/generator" "^7.20.5" + "@babel/parser" "^7.20.5" + "@babel/plugin-transform-typescript" "^7.20.2" + "@babel/preset-typescript" "^7.18.6" + "@babel/traverse" "^7.20.5" + lodash.merge "^4.6.2" + +"@gluestack-style/react@0.1.31": + version "0.1.31" + resolved "https://registry.yarnpkg.com/@gluestack-style/react/-/react-0.1.31.tgz#07e6740d448a49fa0133b6d94dc6239509f6b2df" + integrity sha512-SXVpHJSoNSVFZbOhQVlHInHMloKmZbW0tTzsxbktJcbt0r54dR1o+hsSXfsOBf5aJYLEKaT2jnjXxXAJRE6nOw== + dependencies: + inline-style-prefixer "^6.0.1" + normalize-css-color "^1.0.2" + "@gluestack-style/react@^0.1.11", "@gluestack-style/react@^0.1.33": version "0.1.33" resolved "https://registry.yarnpkg.com/@gluestack-style/react/-/react-0.1.33.tgz#cd18f38bf359527e4f79d223bb07e9024f40ba4f" From 0dcde8c5ceb3e1a5aebc8e110568a589fcfa3370 Mon Sep 17 00:00:00 2001 From: ankit-tailor Date: Wed, 6 Sep 2023 12:57:00 +0530 Subject: [PATCH 2/4] fix: styled and components path based resolution --- .../babel-plugin-styled-resolver/package.json | 2 +- .../babel-plugin-styled-resolver/src/index.js | 331 ++++++++++-------- 2 files changed, 183 insertions(+), 150 deletions(-) diff --git a/packages/babel-plugin-styled-resolver/package.json b/packages/babel-plugin-styled-resolver/package.json index 28b10d056..c2ec716c4 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.1", + "version": "0.2.2-alpha.1", "description": "A gluestack-style babel plugin that transpiles your styled function calls and resolves the component styling in build time.", "keywords": [ "css-in-js", diff --git a/packages/babel-plugin-styled-resolver/src/index.js b/packages/babel-plugin-styled-resolver/src/index.js index 5095daaea..806972889 100644 --- a/packages/babel-plugin-styled-resolver/src/index.js +++ b/packages/babel-plugin-styled-resolver/src/index.js @@ -346,15 +346,7 @@ function isStyledImportedFromLibrary(styled, importName) { function isStyledImportFromAbsolutePath(styled, importName) { for (const styledPath of styled) { - const filePath = styledPath.split('/'); - filePath.pop(); - - const absoluteStyledImportPath = path.resolve( - filePath.join('/'), - importName - ); - - if (importName === absoluteStyledImportPath) { + if (importName === styledPath) { return true; } } @@ -429,6 +421,8 @@ module.exports = function (b) { const guessingStyledComponents = []; const styled = ['@gluestack-style/react']; const components = ['@gluestack-ui/themed']; + let isStyledPathConfigured = false; + let isComponentsPathConfigured = false; return { name: 'ast-transform', // not required @@ -470,18 +464,39 @@ module.exports = function (b) { } } - if (state?.opts?.styled && Array.isArray(state?.opts?.styled)) { + if ( + state?.opts?.styled && + Array.isArray(state?.opts?.styled) && + !isStyledPathConfigured + ) { styled.push(...state?.opts?.styled); + isStyledPathConfigured = true; } - if (state?.opts?.components && Array.isArray(state?.opts?.components)) { + if ( + state?.opts?.components && + Array.isArray(state?.opts?.components) && + !isComponentsPathConfigured + ) { components.push(...state?.opts?.components); + isComponentsPathConfigured = true; } const importName = importPath.node.source.value; + let filePath = state.file.opts.filename.split('/'); + filePath.pop(); + + const absoluteStyledImportPath = path.resolve( + filePath.join('/'), + importName + ); + if ( - isStyledImportFromAbsolutePath(components, importName) || + isStyledImportFromAbsolutePath( + components, + absoluteStyledImportPath + ) || isStyledImportedFromLibrary(components, importName) ) { importPath.traverse({ @@ -494,7 +509,7 @@ module.exports = function (b) { } if ( - isStyledImportFromAbsolutePath(styled, importName) || + isStyledImportFromAbsolutePath(styled, absoluteStyledImportPath) || isStyledImportedFromLibrary(styled, importName) ) { importPath.traverse({ @@ -529,150 +544,162 @@ module.exports = function (b) { if (isValidConfig) { let args = callExpressionPath.node.arguments; - let componentThemeNode = args[1]; - // optional case - let componentConfigNode = args[2] ?? t.objectExpression([]); - let extendedThemeNode = args[3] ?? t.objectExpression([]); - if ( !( - t.isIdentifier(componentThemeNode) || - t.isIdentifier(componentConfigNode) || - t.isIdentifier(extendedThemeNode) + t.isIdentifier(args[1]) && + t.isIdentifier(args[2]) && + t.isIdentifier(args[3]) ) ) { - // args[1] = t.objectExpression([]); - - let extendedThemeNodeProps = []; - if (extendedThemeNode && extendedThemeNode?.properties) { - extendedThemeNode?.properties.forEach((prop) => { - if (prop.key.name === 'propertyResolver') { - tempPropertyResolverNode = prop; - } else { - extendedThemeNodeProps.push(prop); - } - }); - extendedThemeNode.properties = extendedThemeNodeProps; - } + let componentThemeNode = args[1]; + // optional case + let componentConfigNode = args[2] ?? t.objectExpression([]); + let extendedThemeNode = args[3] ?? t.objectExpression([]); + + if ( + !( + t.isIdentifier(componentThemeNode) || + t.isIdentifier(componentConfigNode) || + t.isIdentifier(extendedThemeNode) + ) + ) { + // args[1] = t.objectExpression([]); + + let extendedThemeNodeProps = []; + if (extendedThemeNode && extendedThemeNode?.properties) { + extendedThemeNode?.properties.forEach((prop) => { + if (prop.key.name === 'propertyResolver') { + tempPropertyResolverNode = prop; + } else { + extendedThemeNodeProps.push(prop); + } + }); + extendedThemeNode.properties = extendedThemeNodeProps; + } - let theme = getObjectFromAstNode(componentThemeNode); - let ExtendedConfig = getObjectFromAstNode(extendedThemeNode); - let componentConfig = getObjectFromAstNode(componentConfigNode); + let theme = getObjectFromAstNode(componentThemeNode); + let ExtendedConfig = getObjectFromAstNode(extendedThemeNode); + let componentConfig = getObjectFromAstNode(componentConfigNode); - if (extendedThemeNode && tempPropertyResolverNode) { - extendedThemeNode.properties.push(tempPropertyResolverNode); - } + if (extendedThemeNode && tempPropertyResolverNode) { + extendedThemeNode.properties.push(tempPropertyResolverNode); + } - // getExportedConfigFromFileString(ConfigDefault); - let mergedPropertyConfig = { - ...ConfigDefault?.propertyTokenMap, - ...propertyTokenMap, - }; - let componentExtendedConfig = merge( - {}, - { - ...ConfigDefault, - propertyTokenMap: { ...mergedPropertyConfig }, - }, - ExtendedConfig - ); + // getExportedConfigFromFileString(ConfigDefault); + let mergedPropertyConfig = { + ...ConfigDefault?.propertyTokenMap, + ...propertyTokenMap, + }; + let componentExtendedConfig = merge( + {}, + { + ...ConfigDefault, + propertyTokenMap: { ...mergedPropertyConfig }, + }, + ExtendedConfig + ); - const verbosedTheme = convertStyledToStyledVerbosed(theme); + if (theme && Object.keys(theme).length > 0) { + const verbosedTheme = convertStyledToStyledVerbosed(theme); - let componentHash = stableHash({ - ...theme, - ...componentConfig, - ...ExtendedConfig, - }); + let componentHash = stableHash({ + ...theme, + ...componentConfig, + ...ExtendedConfig, + }); - if (outputLibrary) { - componentHash = outputLibrary + '-' + componentHash; - } + if (outputLibrary) { + componentHash = outputLibrary + '-' + componentHash; + } - const { styledIds, verbosedStyleIds } = updateOrderUnResolvedMap( - verbosedTheme, - componentHash, - 'boot', - componentConfig, - BUILD_TIME_GLUESTACK_STYLESHEET, - platform - ); + const { styledIds, verbosedStyleIds } = + updateOrderUnResolvedMap( + verbosedTheme, + componentHash, + 'boot', + componentConfig, + BUILD_TIME_GLUESTACK_STYLESHEET, + platform + ); - const toBeInjected = BUILD_TIME_GLUESTACK_STYLESHEET.resolve( - styledIds, - componentExtendedConfig, - ExtendedConfig - ); + const toBeInjected = BUILD_TIME_GLUESTACK_STYLESHEET.resolve( + styledIds, + componentExtendedConfig, + ExtendedConfig + ); - const current_global_map = - BUILD_TIME_GLUESTACK_STYLESHEET.getStyleMap(); + const current_global_map = + BUILD_TIME_GLUESTACK_STYLESHEET.getStyleMap(); - const orderedResolvedTheme = []; + const orderedResolvedTheme = []; - current_global_map?.forEach((styledResolved) => { - if (styledIds.includes(styledResolved?.meta?.cssId)) { - orderedResolvedTheme.push(styledResolved); + 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 + ), + ]); + + while (args.length < 4) { + args.push(t.objectExpression([])); + } + if (!args[4]) { + args.push(resultParamsNode); + } else { + args[4] = resultParamsNode; + } } - }); - - 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 - ), - ]); - - while (args.length < 4) { - args.push(t.objectExpression([])); - } - if (!args[4]) { - args.push(resultParamsNode); - } else { - args[4] = resultParamsNode; } } - } - // console.log( - // '<==================|++++>> final ', - // generate(path.node).code - // ); - // console.log( - // args, - // // resolvedStyles, - // // orderedResolved, - // // ...path.node.arguments, - // // generate(resultParamsNode).code, - // // resultParamsNode, - // // generate(path.node).code, - // 'code' - // ); - // console.log('\n\n >>>>>>>>>>>>>>>>>>>>>\n'); - - // console.log('final', generate(path.node).code); - // console.log('\n >>>>>>>>>>>>>>>>>>>>>\n\n'); + // console.log( + // '<==================|++++>> final ', + // generate(path.node).code + // ); + // console.log( + // args, + // // resolvedStyles, + // // orderedResolved, + // // ...path.node.arguments, + // // generate(resultParamsNode).code, + // // resultParamsNode, + // // generate(path.node).code, + // 'code' + // ); + // console.log('\n\n >>>>>>>>>>>>>>>>>>>>>\n'); + + // console.log('final', generate(path.node).code); + // console.log('\n >>>>>>>>>>>>>>>>>>>>>\n\n'); + } } }, JSXOpeningElement(jsxOpeningElementPath) { @@ -767,12 +794,14 @@ module.exports = function (b) { if (componentSXProp[key]) delete utilityPropsWithIdentifier[key]; } + jsxOpeningElementPath.node.attributes = propsToBePersist; + const sx = { ...componentUtilityProps, ...componentSXProp, }; - if (sx) { + if (Object.keys(sx).length > 0) { const verbosedSx = convertSxToSxVerbosed(sx); const inlineSxTheme = { @@ -836,16 +865,6 @@ module.exports = function (b) { styledIds?.map((cssId) => t.stringLiteral(cssId)) ); - jsxOpeningElementPath.node.attributes = propsToBePersist; - - if (Object.keys(sxPropsWithIdentifier).length > 0) { - jsxOpeningElementPath.node.attributes.push( - t.jsxAttribute( - t.jsxIdentifier('sx'), - t.jsxExpressionContainer(sxPropsWithIdentifier) - ) - ); - } jsxOpeningElementPath.node.attributes.push( t.jsxAttribute( t.jsxIdentifier('verbosedStyleIds'), @@ -876,6 +895,20 @@ module.exports = function (b) { ) ); } + + if ( + sxPropsWithIdentifier && + sxPropsWithIdentifier.properties && + sxPropsWithIdentifier.properties.length > 0 + ) { + jsxOpeningElementPath.node.attributes.push( + t.jsxAttribute( + t.jsxIdentifier('sx'), + t.jsxExpressionContainer(sxPropsWithIdentifier) + ) + ); + } + componentSXProp = undefined; componentUtilityProps = undefined; } From 853e8fc90c825adbf6359a05e1108ec6c36d42ad Mon Sep 17 00:00:00 2001 From: ankit-tailor Date: Wed, 6 Sep 2023 12:57:57 +0530 Subject: [PATCH 3/4] fix: add example --- example/ui-examples-babel/App.tsx | 66 +- example/ui-examples-babel/BenchGlueStack.tsx | 70 + .../ui-examples-babel/BenchReactNative.tsx | 22 + example/ui-examples-babel/TimeRenderer.js | 27 + example/ui-examples-babel/TimedRender.js | 27 + example/ui-examples-babel/babel.config.js | 13 +- example/ui-examples-babel/data.ts | 156 + .../gluestack-components/Button/index.tsx | 20 + .../Button/styled-components/Group.tsx | 120 + .../Button/styled-components/GroupHSpacer.tsx | 28 + .../Button/styled-components/GroupVSpacer.tsx | 28 + .../Button/styled-components/Icon.tsx | 43 + .../Button/styled-components/Root.tsx | 1031 ++ .../Button/styled-components/Spinner.tsx | 8 + .../Button/styled-components/Text.tsx | 13 + .../Button/styled-components/index.tsx | 7 + .../gluestack-components/HStack/index.tsx | 7 + .../HStack/styled-components/Root.tsx | 14 + .../HStack/styled-components/Spacer.tsx | 37 + .../HStack/styled-components/index.tsx | 2 + .../gluestack-components/Image/index.tsx | 3 + .../Image/styled-components/FallbackText.tsx | 13 + .../Image/styled-components/Root.tsx | 53 + .../Image/styled-components/index.tsx | 1 + .../gluestack-components/Provider/index.tsx | 19 + .../gluestack-components/Text/index.tsx | 2 + .../Text/styled-components/Root.tsx | 120 + .../Text/styled-components/index.tsx | 1 + .../gluestack-components/VStack/config.json | 4 + .../gluestack-components/VStack/index.tsx | 7 + .../VStack/styled-components/Root.tsx | 13 + .../VStack/styled-components/Spacer.tsx | 37 + .../VStack/styled-components/index.tsx | 2 + .../gluestack-components/index.ts | 6 + .../ui-examples-babel/gluestack-ui.config.ts | 218 +- example/ui-examples-babel/index.js | 38 - example/ui-examples-babel/package.json | 3 +- .../src/core/Heading/styled-heading.tsx | 2 +- example/ui-examples-babel/yarn.lock | 11110 ++++++++++++++++ 39 files changed, 13217 insertions(+), 174 deletions(-) create mode 100644 example/ui-examples-babel/BenchGlueStack.tsx create mode 100644 example/ui-examples-babel/BenchReactNative.tsx create mode 100644 example/ui-examples-babel/TimeRenderer.js create mode 100644 example/ui-examples-babel/TimedRender.js create mode 100644 example/ui-examples-babel/data.ts create mode 100644 example/ui-examples-babel/gluestack-components/Button/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/Group.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/GroupHSpacer.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/GroupVSpacer.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/Icon.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/Root.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/Spinner.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/Text.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Button/styled-components/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/HStack/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/HStack/styled-components/Root.tsx create mode 100644 example/ui-examples-babel/gluestack-components/HStack/styled-components/Spacer.tsx create mode 100644 example/ui-examples-babel/gluestack-components/HStack/styled-components/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Image/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Image/styled-components/FallbackText.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Image/styled-components/Root.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Image/styled-components/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Provider/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Text/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Text/styled-components/Root.tsx create mode 100644 example/ui-examples-babel/gluestack-components/Text/styled-components/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/VStack/config.json create mode 100644 example/ui-examples-babel/gluestack-components/VStack/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/VStack/styled-components/Root.tsx create mode 100644 example/ui-examples-babel/gluestack-components/VStack/styled-components/Spacer.tsx create mode 100644 example/ui-examples-babel/gluestack-components/VStack/styled-components/index.tsx create mode 100644 example/ui-examples-babel/gluestack-components/index.ts create mode 100644 example/ui-examples-babel/yarn.lock diff --git a/example/ui-examples-babel/App.tsx b/example/ui-examples-babel/App.tsx index 294226542..df56c4b84 100644 --- a/example/ui-examples-babel/App.tsx +++ b/example/ui-examples-babel/App.tsx @@ -1,22 +1,58 @@ import React from 'react'; -import { View } from 'react-native'; -import { config } from './gluestack-ui.config'; -import { styled, StyledProvider } from '../../packages/react'; -// import { Box, Heading } from './src/core'; +import { useState } from 'react'; +import { Button, StyleSheet, Text, View } from 'react-native'; -const Box = styled(View, { - bg: '$primary100', - h: '$10', - w: '$10', -}); +import Gluestack from './BenchGlueStack'; +import ReactNative from './BenchReactNative'; +import TimedRender from './TimedRender'; export default function App() { + const [styleType, setStyleType] = useState(undefined); + + const onStyleTypePress = (curry) => () => { + setStyleType(curry); + }; + + const renderStyleLibrary = () => { + switch (styleType) { + case 'Gluestack': + return ; + case 'React Native': + return ; + default: + return null; + } + }; + return ( - <> - {/* gluestack-ui provider */} - - - - + + Tap a style library to start rendering +