From 2ff2e4ebb520833ffb8fb2e15f4188ba62dc4874 Mon Sep 17 00:00:00 2001 From: Suraj Date: Tue, 10 Oct 2023 15:03:15 +0530 Subject: [PATCH 01/12] fix: added experimental nested provider" --- packages/react/src/StyledProvider.tsx | 62 +++++++++++++++++++++------ packages/react/src/styled.tsx | 4 +- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/packages/react/src/StyledProvider.tsx b/packages/react/src/StyledProvider.tsx index 758a9e652..ff1d68380 100644 --- a/packages/react/src/StyledProvider.tsx +++ b/packages/react/src/StyledProvider.tsx @@ -1,6 +1,6 @@ import { get, onChange, set } from './core/colorMode'; import * as React from 'react'; -import { Platform } from 'react-native'; +import { Platform, View } from 'react-native'; import { propertyTokenMap } from './propertyTokenMap'; import type { COLORMODES } from './types'; import { platformSpecificSpaceUnits } from './utils'; @@ -42,7 +42,14 @@ export const StyledProvider: React.FC<{ colorMode?: COLORMODES; children?: React.ReactNode; globalStyles?: any; -}> = ({ config, colorMode, children, globalStyles }) => { + _experimentalNestedProvider: boolean; +}> = ({ + config, + colorMode, + children, + globalStyles, + _experimentalNestedProvider, +}) => { const currentConfig: any = React.useMemo(() => { //TODO: Add this later return platformSpecificSpaceUnits(config, Platform.OS); @@ -57,11 +64,22 @@ export const StyledProvider: React.FC<{ return colorMode ?? get() ?? 'light'; }, [colorMode]); + const _experimentalNestedProviderRef = React.useRef(null); React.useEffect(() => { + let documentElement: any = null; + + if (Platform.OS === 'web') { + if (_experimentalNestedProvider) { + // write own code for nested colorMode + documentElement = _experimentalNestedProviderRef.current; + } else { + documentElement = document.documentElement; + } + } // Add gs class name if (Platform.OS === 'web') { - document.documentElement.classList.add(`gs`); - document.documentElement.classList.add(`gs-${currentColorMode}`); + documentElement.classList.add(`gs`); + documentElement.classList.add(`gs-${currentColorMode}`); } // GluestackStyleSheet.resolve({ ...config, propertyTokenMap }); @@ -69,13 +87,17 @@ export const StyledProvider: React.FC<{ onChange((currentColor: string) => { // only for web - if (Platform.OS === 'web') { - if (currentColor === 'dark') { - document.documentElement.classList.remove(`gs-light`); - } else { - document.documentElement.classList.remove(`gs-dark`); + if (!_experimentalNestedProviderRef) { + const documentElement = document.documentElement; + + if (Platform.OS === 'web') { + if (currentColor === 'dark') { + documentElement.classList.remove(`gs-light`); + } else { + documentElement.classList.remove(`gs-dark`); + } + documentElement.classList.add(`gs-${currentColor}`); } - document.documentElement.classList.add(`gs-${currentColor}`); } }); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -95,19 +117,35 @@ export const StyledProvider: React.FC<{ config?.globalStyle && createGlobalStyles(config.globalStyle); const contextValue = React.useMemo(() => { - return { + const styledData = { config: currentConfig, globalStyle: globalStyleMap, animationDriverData, setAnimationDriverData, }; + if (_experimentalNestedProvider) { + //@ts-ignore + styledData._experimentalNestedProvider = _experimentalNestedProvider; + //@ts-ignore + styledData.colorMode = colorMode; + } + return styledData; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [currentConfig, globalStyleMap, animationDriverData]); - return ( + const providerComponent = ( {children} ); + + if (_experimentalNestedProvider) { + return ( + {providerComponent} + ); + } else { + return <>{providerComponent}; + } }; export const useStyled = () => React.useContext(StyledContext); diff --git a/packages/react/src/styled.tsx b/packages/react/src/styled.tsx index 301b16911..1847ad7e2 100644 --- a/packages/react/src/styled.tsx +++ b/packages/react/src/styled.tsx @@ -1030,7 +1030,9 @@ export function verboseStyled( const sxCompoundVariantFlatternStyleObject = React.useRef({}); const sxDescendantFlattenStyles: any = React.useRef({}); - const COLOR_MODE: any = get(); + const COLOR_MODE: any = styledContext._experimentalNestedProvider + ? styledContext.colorMode + : get(); if (!styleHashCreated) { CONFIG = { From fdbf3b70c0dd89346938a4539fee1aec8692a0b4 Mon Sep 17 00:00:00 2001 From: Suraj Date: Tue, 10 Oct 2023 15:04:20 +0530 Subject: [PATCH 02/12] v1.0.2-alpha.0 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index f386b944f..b02477e74 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": "1.0.1", + "version": "1.0.2-alpha.0", "keywords": [ "React Native", "Next.js", From 9bf83a91540482f2f41c2cca6dc0a2904a611660 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 11:56:37 +0530 Subject: [PATCH 03/12] v1.0.2-alpha.1 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index b02477e74..659b12899 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": "1.0.2-alpha.0", + "version": "1.0.2-alpha.1", "keywords": [ "React Native", "Next.js", From fbbd2b8cb18f85c2666245cd39d5da98a11e2f46 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 15:03:37 +0530 Subject: [PATCH 04/12] v1.0.2-alpha.3 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 659b12899..2490dce05 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": "1.0.2-alpha.1", + "version": "1.0.2-alpha.3", "keywords": [ "React Native", "Next.js", From bda322e3afeaddf572885c6bcb4fed2bb2b83bd6 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 15:07:27 +0530 Subject: [PATCH 05/12] v1.0.2-alpha.4 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 2490dce05..2881c0cd4 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": "1.0.2-alpha.3", + "version": "1.0.2-alpha.4", "keywords": [ "React Native", "Next.js", From c10daf0c1158a96f284a2d03fc5b16f31f509a73 Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 15:14:09 +0530 Subject: [PATCH 06/12] v1.0.2-alpha.5 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 2881c0cd4..9eda2b530 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": "1.0.2-alpha.4", + "version": "1.0.2-alpha.5", "keywords": [ "React Native", "Next.js", From ac754d5a0fd72e38df0e69dcd1a23205a320eb8f Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 15:51:33 +0530 Subject: [PATCH 07/12] v1.0.2-alpha.6 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 9eda2b530..658e94700 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": "1.0.2-alpha.5", + "version": "1.0.2-alpha.6", "keywords": [ "React Native", "Next.js", From 5ebe175311a33704b14e64bea03c313abfb6c31b Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 16:02:28 +0530 Subject: [PATCH 08/12] v1.0.2-alpha.7 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 658e94700..9d2b2ba83 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": "1.0.2-alpha.6", + "version": "1.0.2-alpha.7", "keywords": [ "React Native", "Next.js", From 5cbbe40c46ff85b0d2ebc2b4d75d6a1f6d1557fd Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 16:18:18 +0530 Subject: [PATCH 09/12] v1.0.2-alpha.8 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 9d2b2ba83..24562cf5e 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": "1.0.2-alpha.7", + "version": "1.0.2-alpha.8", "keywords": [ "React Native", "Next.js", From e7155025029b9e9e3a726d1e4b4dcb8d193804eb Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 16:25:20 +0530 Subject: [PATCH 10/12] fix: web performance issue --- .../DescendantsStyles/ContextBasedStyles.tsx | 16 ++++---- packages/react/src/StyledProvider.tsx | 39 ++++++++++++++++++ .../injectComponentAndDescendantStyles.ts | 5 ++- packages/react/src/style-sheet/index.ts | 23 +++++++++-- packages/react/src/styled.tsx | 41 ++++++++++++++----- .../src/utils/css-injector/utils/inject.ts | 5 ++- .../utils/css-injector/utils/inject.web.ts | 22 ++++++++-- 7 files changed, 124 insertions(+), 27 deletions(-) diff --git a/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx b/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx index 03351aa26..ed6a9271a 100644 --- a/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx +++ b/example/storybook/src/api/DescendantsStyles/ContextBasedStyles.tsx @@ -116,8 +116,12 @@ const Text1 = styled( } ); -const MyLink = styled(Link, {}); +const Box = styled(View, { + bg: '$blue500', + p: '$10', +}); export function ContextBasedStyles() { + console.log('>>>>> component'); return ( {/* */} @@ -129,14 +133,12 @@ export function ContextBasedStyles() { > vdkbkdfbv */} - - next link - + > ); } diff --git a/packages/react/src/StyledProvider.tsx b/packages/react/src/StyledProvider.tsx index ff1d68380..09c7676bb 100644 --- a/packages/react/src/StyledProvider.tsx +++ b/packages/react/src/StyledProvider.tsx @@ -6,6 +6,7 @@ import type { COLORMODES } from './types'; import { platformSpecificSpaceUnits } from './utils'; import { createGlobalStylesWeb } from './createGlobalStylesWeb'; import { createGlobalStyles } from './createGlobalStyles'; + type Config = any; let colorModeSet = false; @@ -50,6 +51,11 @@ export const StyledProvider: React.FC<{ globalStyles, _experimentalNestedProvider, }) => { + const inlineStyleMap: any = React.useRef({ + initialStyleInjected: false, + }); + inlineStyleMap.current.initialStyleInjected = false; + const currentConfig: any = React.useMemo(() => { //TODO: Add this later return platformSpecificSpaceUnits(config, Platform.OS); @@ -107,6 +113,38 @@ export const StyledProvider: React.FC<{ setCurrentColorMode(currentColorMode); }, [currentColorMode]); + React.useLayoutEffect(() => { + if (Platform.OS === 'web') { + const toBeInjectedStyles: any = {}; + + if (inlineStyleMap.current.initialStyleInjected) { + return; + } + + Object.keys(inlineStyleMap.current).forEach((key: any) => { + if (key !== 'initialStyleInjected') { + const styles = inlineStyleMap.current[key]; + if (!toBeInjectedStyles[key]) { + toBeInjectedStyles[key] = document.createDocumentFragment(); + } + + styles.forEach((style: any) => { + if (!document.getElementById(style.id)) { + toBeInjectedStyles[key].appendChild(style); + } + }); + } + }); + Object.keys(toBeInjectedStyles).forEach((key) => { + let wrapperElement = document.querySelector('#' + key); + if (wrapperElement) { + wrapperElement.appendChild(toBeInjectedStyles[key]); + } + // delete inlineStyleMap.current[key]; + }); + inlineStyleMap.current.initialStyleInjected = true; + } + }); // // Set colormode for the first time if (!colorModeSet) { setCurrentColorMode(currentColorMode); @@ -122,6 +160,7 @@ export const StyledProvider: React.FC<{ globalStyle: globalStyleMap, animationDriverData, setAnimationDriverData, + inlineStyleMap: inlineStyleMap.current, }; if (_experimentalNestedProvider) { //@ts-ignore diff --git a/packages/react/src/resolver/injectComponentAndDescendantStyles.ts b/packages/react/src/resolver/injectComponentAndDescendantStyles.ts index 913ac2f71..b3a37804b 100644 --- a/packages/react/src/resolver/injectComponentAndDescendantStyles.ts +++ b/packages/react/src/resolver/injectComponentAndDescendantStyles.ts @@ -12,7 +12,8 @@ export function injectComponentAndDescendantStyles( styleTagId?: string, type: 'boot' | 'inline' = 'boot', _GluestackStyleSheet: StyleInjector = GluestackStyleSheet, - platform: string = '' + platform: string = '', + inlineStyleMap?: any ) { const [ componentOrderResolvedBaseStyle, @@ -84,7 +85,7 @@ export function injectComponentAndDescendantStyles( ); if (platform === 'web') { - GluestackStyleSheet.inject(toBeInjected); + GluestackStyleSheet.inject(toBeInjected, inlineStyleMap); } return styleCSSIdsArr; diff --git a/packages/react/src/style-sheet/index.ts b/packages/react/src/style-sheet/index.ts index ee7f34d14..d3d82f311 100644 --- a/packages/react/src/style-sheet/index.ts +++ b/packages/react/src/style-sheet/index.ts @@ -109,10 +109,15 @@ export class StyleInjector { return toBeInjected; } - inject(toBeInjected: any = {}) { + inject(toBeInjected: any = {}, inlineStyleMap: any) { Object.keys(toBeInjected).forEach((type) => { Object.keys(toBeInjected[type]).forEach((styleTag) => { - this.injectStyles(toBeInjected[type][styleTag], type, styleTag); + this.injectStyles( + toBeInjected[type][styleTag], + type, + styleTag, + inlineStyleMap + ); }); }); } @@ -162,9 +167,19 @@ export class StyleInjector { return this.#globalStyleMap; } - injectStyles(cssRuleset: any, _wrapperType: any, _styleTagId: any) { + injectStyles( + cssRuleset: any, + _wrapperType: any, + _styleTagId: any, + inlineStyleMap: any + ) { if (cssRuleset) { - inject(`@media screen {${cssRuleset}}`, _wrapperType as any, _styleTagId); + inject( + `@media screen {${cssRuleset}}`, + _wrapperType as any, + _styleTagId, + inlineStyleMap + ); } } } diff --git a/packages/react/src/styled.tsx b/packages/react/src/styled.tsx index 1847ad7e2..3b644e1c1 100644 --- a/packages/react/src/styled.tsx +++ b/packages/react/src/styled.tsx @@ -906,7 +906,7 @@ export function verboseStyled( styleIds = BUILD_TIME_PARAMS?.verbosedStyleIds; } - function injectSx(sx: any, type: any = 'inline') { + function injectSx(sx: any, type: any = 'inline', inlineStyleMap?: any) { const inlineSxTheme = { baseStyle: sx, }; @@ -965,7 +965,8 @@ export function verboseStyled( sxHash, type, GluestackStyleSheet, - Platform.OS + Platform.OS, + inlineStyleMap ); return orderedSXResolved; @@ -1059,7 +1060,6 @@ export function verboseStyled( // const resolvedComponentExtendedTheme = EXTENDED_THEME; theme = deepMerge(theme, resolvedComponentExtendedTheme.theme); - // @ts-ignore Object.assign(themeDefaultProps, theme?.baseStyle?.props); if (Object.keys(EXTENDED_THEME?.BUILD_TIME_PARAMS ?? {}).length > 0) { @@ -1070,7 +1070,8 @@ export function verboseStyled( EXTENDED_THEME_BUILD_TIME_PARAMS?.verbosedStyleIds ); GluestackStyleSheet.inject( - EXTENDED_THEME_BUILD_TIME_PARAMS?.toBeInjected + EXTENDED_THEME_BUILD_TIME_PARAMS?.toBeInjected, + styledContext.inlineStyleMap ); } else { // Merge of Extended Config Style ID's with Component Style ID's @@ -1084,7 +1085,10 @@ export function verboseStyled( CONFIG, componentExtendedConfig ); - GluestackStyleSheet.inject(extendedStylesToBeInjected); + GluestackStyleSheet.inject( + extendedStylesToBeInjected, + styledContext.inlineStyleMap + ); } } @@ -1133,12 +1137,18 @@ export function verboseStyled( componentExtendedConfig ); if (Platform.OS === 'web') { - GluestackStyleSheet.inject(toBeInjected); + GluestackStyleSheet.inject( + toBeInjected, + styledContext.inlineStyleMap + ); } } else { if (Platform.OS === 'web') { //@ts-ignore - GluestackStyleSheet.inject(BUILD_TIME_PARAMS.toBeInjected); + GluestackStyleSheet.inject( + BUILD_TIME_PARAMS.toBeInjected, + styledContext.inlineStyleMap + ); } } @@ -1229,7 +1239,10 @@ export function verboseStyled( ); if (Platform.OS === 'web') { - GluestackStyleSheet.inject(toBeInjected); + GluestackStyleSheet.inject( + toBeInjected, + styledContext.inlineStyleMap + ); } isInjected = true; } @@ -1432,11 +1445,19 @@ export function verboseStyled( function injectAndUpdateSXProps(filteredPassingSx: any) { if (Object.keys(filteredComponentSx).length > 0) { - orderedComponentSXResolved = injectSx(filteredComponentSx, 'inline'); + orderedComponentSXResolved = injectSx( + filteredComponentSx, + 'inline', + styledContext.inlineStyleMap + ); } if (Object.keys(filteredPassingSx).length > 0) { - orderedPassingSXResolved = injectSx(filteredPassingSx, 'passing'); + orderedPassingSXResolved = injectSx( + filteredPassingSx, + 'passing', + styledContext.inlineStyleMap + ); } const orderedSXResolved = [ diff --git a/packages/react/src/utils/css-injector/utils/inject.ts b/packages/react/src/utils/css-injector/utils/inject.ts index b0f316b8b..bba2b8ed5 100644 --- a/packages/react/src/utils/css-injector/utils/inject.ts +++ b/packages/react/src/utils/css-injector/utils/inject.ts @@ -5,13 +5,16 @@ type IWrapperType = | 'boot-descendant' | 'inline-descendant'; +export const WRAPPER_BLOCK_PREFIX = 'gs-injected'; + export const hasCss = (_id: any, _text: any) => {}; export const addCss = (_id: any, _text: any) => {}; export const injectCss = ( _css: any, _wrapperType: IWrapperType, - _styleTagId: string + _styleTagId: string, + _inlineStyleMap?: any ) => {}; export const injectGlobalCss = ( _css: any, diff --git a/packages/react/src/utils/css-injector/utils/inject.web.ts b/packages/react/src/utils/css-injector/utils/inject.web.ts index 8fa26f04a..443e50719 100644 --- a/packages/react/src/utils/css-injector/utils/inject.web.ts +++ b/packages/react/src/utils/css-injector/utils/inject.web.ts @@ -117,7 +117,8 @@ const createStyle = (styleTagId: any, css: any) => { export const injectCss = ( css: any, wrapperType: IWrapperType, - styleTagId: string + styleTagId: string, + inlineStyleMap?: any ) => { // let modifiedStylesheet = {} as any; if (!toBeFlushedStyles[wrapperType]) { @@ -138,8 +139,23 @@ export const injectCss = ( if (!style) { style = createStyle(styleTagId, css); - // wrapperElement.insertBefore(style, wrapperElement.firstChild); - wrapperElement.appendChild(style); + // console.log(inlineStyleMap, 'append child here >>>>>'); + if (inlineStyleMap) { + if (!inlineStyleMap?.initialStyleInjected) { + const styleMapId = `${WRAPPER_BLOCK_PREFIX}-${wrapperType}`; + const inlineMapStyles = inlineStyleMap[styleMapId]; + + if (inlineMapStyles) { + inlineMapStyles.push(style); + } else { + inlineStyleMap[styleMapId] = [style]; + } + // console.log('hello here >>>> there'); + } else { + // console.log('hello here >>>>'); + wrapperElement.appendChild(style); + } + } } } } From 17910862905333d36d69b23b1320d8b1d8321e3b Mon Sep 17 00:00:00 2001 From: ankit-tailor Date: Wed, 11 Oct 2023 16:44:42 +0530 Subject: [PATCH 11/12] fix: experimental provider for color mode change --- packages/react/src/StyledProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react/src/StyledProvider.tsx b/packages/react/src/StyledProvider.tsx index 09c7676bb..45b7dfad0 100644 --- a/packages/react/src/StyledProvider.tsx +++ b/packages/react/src/StyledProvider.tsx @@ -93,7 +93,7 @@ export const StyledProvider: React.FC<{ onChange((currentColor: string) => { // only for web - if (!_experimentalNestedProviderRef) { + if (!_experimentalNestedProvider) { const documentElement = document.documentElement; if (Platform.OS === 'web') { @@ -162,6 +162,7 @@ export const StyledProvider: React.FC<{ setAnimationDriverData, inlineStyleMap: inlineStyleMap.current, }; + if (_experimentalNestedProvider) { //@ts-ignore styledData._experimentalNestedProvider = _experimentalNestedProvider; From f0a368d28dd9ede50565f32865267d5226fdd90c Mon Sep 17 00:00:00 2001 From: Suraj Date: Wed, 11 Oct 2023 16:45:27 +0530 Subject: [PATCH 12/12] v1.0.2 --- packages/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/package.json b/packages/react/package.json index 24562cf5e..c16ccde4b 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": "1.0.2-alpha.8", + "version": "1.0.2", "keywords": [ "React Native", "Next.js",