I have this white label context that I want to create but it seems everytime I load a designToken and a Partner Asset it render the component with the default value for a small time and then changes to the other value. Just want to know a way to only render when I have a value that is good to be rendered.
<code>import { createContext, useState, useEffect, ReactNode } from 'react';
import { useParams } from 'react-router-dom';
import useAuth from '@hooks/useAuth.tsx';
import logger from '@utils/logger';
import { DEFAULT_OHT_WHITE_LABEL_STYLE } from '@routes/SignIn';
import { designTokens } from '../tokens/oht/designTokens.ts';
import { applyDesignTokens } from '../tokens/applyDesignTokens.ts';
import defaultLogo from '@assets/OpenHealthLogo.png';
import defaultLogoSidebar from '@assets/OpenHealthLogoSidebar.png';
import defaultBackgroundBanner1 from '@assets/background-banner1.png';
import defaultBackgroundBanner2 from '@assets/background-banner2.png';
import defaultBackgroundBanner3 from '@assets/background-banner3.png';
const defaultAssets: Record<string, string> = {
logo: defaultLogo,
logoSidebar: defaultLogoSidebar,
backgroundBanner1: defaultBackgroundBanner1,
backgroundBanner2: defaultBackgroundBanner2,
backgroundBanner3: defaultBackgroundBanner3,
};
interface WhiteLabelContextProps {
partnerAssets: Record<string, any> | null;
designTokens: Record<string, any> | null;
}
const partnerAssets = import.meta.glob([
'../tokens/WhiteLabelStyle/*/assets/*.{png,jpg,jpeg,svg}',
]);
const partnerDesignTokens = import.meta.glob(
'../tokens/WhiteLabelStyle/*/designTokens.{ts,tsx,js,jsx}'
);
const colorPattern =
/^oht-(neutral-(light|gray|dark)|brand-(p|s|t)|system-(negative|danger|positive)-(p|s))-d{3}$/;
const fontFamilyPattern = /^font-oht-family-(inter)$/;
const fontSizePattern = /^oht-d{3,4}$/;
const lineHeightPattern = /^oht-d{3,4}$/;
const fontWeightPattern = /^oht-(normal|medium|semibold|bold)$/;
const spacingPattern = /^oht-d{2,4}$/;
const borderRadiusPattern = /^oht-d{2,4}$/;
const borderWidthPattern = /^oht-d{2,3}$/;
const tokenRegexMap = {
colors: colorPattern,
fontFamily: fontFamilyPattern,
fontSize: fontSizePattern,
lineHeight: lineHeightPattern,
fontWeight: fontWeightPattern,
spacing: spacingPattern,
borderRadius: borderRadiusPattern,
borderWidth: borderWidthPattern,
};
export const getPartnerAssets = async (whiteLabelStyle?: string) => {
try {
if (whiteLabelStyle && whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE) {
const files = Object.keys(partnerAssets).filter(f =>
f.includes(whiteLabelStyle)
);
const assets: Record<string, string> = {};
for (const file of files) {
const fileName = file.split('/').pop() ?? '';
const key = fileName.split('.')[0]; // e.g., 'logo', 'image1', etc.
const fileModule: any = await partnerAssets[file]();
assets[key] = fileModule.default;
}
return assets;
}
} catch (error) {
logger.error('Failed to load images and logo', error);
return defaultAssets;
}
// Return empty object if no whiteLabelStyle or files not found
return defaultAssets;
};
export const getDesignTokens = async (whiteLabelStyle?: string) => {
try {
if (whiteLabelStyle && whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE) {
const path = Object.keys(partnerDesignTokens).find(f =>
f.includes(whiteLabelStyle)
);
if (path) {
const partnerTokens: any = await partnerDesignTokens[path]();
if (partnerTokens?.designTokens) {
return partnerTokens.designTokens;
}
}
}
} catch (error) {
return designTokens;
}
// If no partner or partner file doesn't exist, use the default tokens
return designTokens;
};
const validateTokenNames = (tokens?: any): boolean => {
if (!tokens) {
return false;
}
try {
const invalidTokens: string[] = [];
Object.keys(tokens).forEach(key => {
Object.keys(tokens[key]).forEach(token => {
if (!tokenRegexMap[key].test(token)) {
invalidTokens.push(token);
}
});
});
if (invalidTokens.length > 0) {
logger.warn('Invalid tokens:', invalidTokens);
return false;
}
return true;
} catch (_err) {
logger.warn('Error validating the tokens, Invalid tokens');
return false;
}
};
export const initializeDesignTokens = async (tokens: any) => {
try {
const isValid = validateTokenNames(tokens);
if (!isValid) {
throw new Error('Invalid token names detected.');
}
if (tokens) {
applyDesignTokens(tokens);
} else {
applyDesignTokens(designTokens);
}
} catch (error) {
logger.error('Failed to load or validate tokens for partner', error);
return designTokens;
}
};
const WhiteLabelContext = createContext<WhiteLabelContextProps | undefined>(
undefined
);
export const WhiteLabelProvider = ({ children }: { children: ReactNode }) => {
const params = useParams();
const { partnerStyleConfig } = useAuth();
const [partnerAssets, setPartnerAssets] = useState<Record<
string,
any
> | null>(null);
const [designTokens, setDesignTokens] = useState<Record<string, any> | null>(
null
);
useEffect(() => {
const fetchAssetsAndTokens = async () => {
let assets = await getPartnerAssets(DEFAULT_OHT_WHITE_LABEL_STYLE);
let tokens = await getDesignTokens(DEFAULT_OHT_WHITE_LABEL_STYLE);
if (
partnerStyleConfig?.whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE
) {
assets = await getPartnerAssets(partnerStyleConfig?.whiteLabelStyle);
tokens = await getDesignTokens(partnerStyleConfig?.whiteLabelStyle);
}
await initializeDesignTokens(tokens);
setPartnerAssets(assets);
setDesignTokens(tokens);
};
// remove this if not using WhiteLabelParams
fetchAssetsAndTokens();
}, [params.whiteLabelStyle, partnerStyleConfig?.whiteLabelStyle]);
return (
<WhiteLabelContext.Provider value={{ partnerAssets, designTokens }}>
{children}
</WhiteLabelContext.Provider>
);
};
export default WhiteLabelContext;
</code>
<code>import { createContext, useState, useEffect, ReactNode } from 'react';
import { useParams } from 'react-router-dom';
import useAuth from '@hooks/useAuth.tsx';
import logger from '@utils/logger';
import { DEFAULT_OHT_WHITE_LABEL_STYLE } from '@routes/SignIn';
import { designTokens } from '../tokens/oht/designTokens.ts';
import { applyDesignTokens } from '../tokens/applyDesignTokens.ts';
import defaultLogo from '@assets/OpenHealthLogo.png';
import defaultLogoSidebar from '@assets/OpenHealthLogoSidebar.png';
import defaultBackgroundBanner1 from '@assets/background-banner1.png';
import defaultBackgroundBanner2 from '@assets/background-banner2.png';
import defaultBackgroundBanner3 from '@assets/background-banner3.png';
const defaultAssets: Record<string, string> = {
logo: defaultLogo,
logoSidebar: defaultLogoSidebar,
backgroundBanner1: defaultBackgroundBanner1,
backgroundBanner2: defaultBackgroundBanner2,
backgroundBanner3: defaultBackgroundBanner3,
};
interface WhiteLabelContextProps {
partnerAssets: Record<string, any> | null;
designTokens: Record<string, any> | null;
}
const partnerAssets = import.meta.glob([
'../tokens/WhiteLabelStyle/*/assets/*.{png,jpg,jpeg,svg}',
]);
const partnerDesignTokens = import.meta.glob(
'../tokens/WhiteLabelStyle/*/designTokens.{ts,tsx,js,jsx}'
);
const colorPattern =
/^oht-(neutral-(light|gray|dark)|brand-(p|s|t)|system-(negative|danger|positive)-(p|s))-d{3}$/;
const fontFamilyPattern = /^font-oht-family-(inter)$/;
const fontSizePattern = /^oht-d{3,4}$/;
const lineHeightPattern = /^oht-d{3,4}$/;
const fontWeightPattern = /^oht-(normal|medium|semibold|bold)$/;
const spacingPattern = /^oht-d{2,4}$/;
const borderRadiusPattern = /^oht-d{2,4}$/;
const borderWidthPattern = /^oht-d{2,3}$/;
const tokenRegexMap = {
colors: colorPattern,
fontFamily: fontFamilyPattern,
fontSize: fontSizePattern,
lineHeight: lineHeightPattern,
fontWeight: fontWeightPattern,
spacing: spacingPattern,
borderRadius: borderRadiusPattern,
borderWidth: borderWidthPattern,
};
export const getPartnerAssets = async (whiteLabelStyle?: string) => {
try {
if (whiteLabelStyle && whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE) {
const files = Object.keys(partnerAssets).filter(f =>
f.includes(whiteLabelStyle)
);
const assets: Record<string, string> = {};
for (const file of files) {
const fileName = file.split('/').pop() ?? '';
const key = fileName.split('.')[0]; // e.g., 'logo', 'image1', etc.
const fileModule: any = await partnerAssets[file]();
assets[key] = fileModule.default;
}
return assets;
}
} catch (error) {
logger.error('Failed to load images and logo', error);
return defaultAssets;
}
// Return empty object if no whiteLabelStyle or files not found
return defaultAssets;
};
export const getDesignTokens = async (whiteLabelStyle?: string) => {
try {
if (whiteLabelStyle && whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE) {
const path = Object.keys(partnerDesignTokens).find(f =>
f.includes(whiteLabelStyle)
);
if (path) {
const partnerTokens: any = await partnerDesignTokens[path]();
if (partnerTokens?.designTokens) {
return partnerTokens.designTokens;
}
}
}
} catch (error) {
return designTokens;
}
// If no partner or partner file doesn't exist, use the default tokens
return designTokens;
};
const validateTokenNames = (tokens?: any): boolean => {
if (!tokens) {
return false;
}
try {
const invalidTokens: string[] = [];
Object.keys(tokens).forEach(key => {
Object.keys(tokens[key]).forEach(token => {
if (!tokenRegexMap[key].test(token)) {
invalidTokens.push(token);
}
});
});
if (invalidTokens.length > 0) {
logger.warn('Invalid tokens:', invalidTokens);
return false;
}
return true;
} catch (_err) {
logger.warn('Error validating the tokens, Invalid tokens');
return false;
}
};
export const initializeDesignTokens = async (tokens: any) => {
try {
const isValid = validateTokenNames(tokens);
if (!isValid) {
throw new Error('Invalid token names detected.');
}
if (tokens) {
applyDesignTokens(tokens);
} else {
applyDesignTokens(designTokens);
}
} catch (error) {
logger.error('Failed to load or validate tokens for partner', error);
return designTokens;
}
};
const WhiteLabelContext = createContext<WhiteLabelContextProps | undefined>(
undefined
);
export const WhiteLabelProvider = ({ children }: { children: ReactNode }) => {
const params = useParams();
const { partnerStyleConfig } = useAuth();
const [partnerAssets, setPartnerAssets] = useState<Record<
string,
any
> | null>(null);
const [designTokens, setDesignTokens] = useState<Record<string, any> | null>(
null
);
useEffect(() => {
const fetchAssetsAndTokens = async () => {
let assets = await getPartnerAssets(DEFAULT_OHT_WHITE_LABEL_STYLE);
let tokens = await getDesignTokens(DEFAULT_OHT_WHITE_LABEL_STYLE);
if (
partnerStyleConfig?.whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE
) {
assets = await getPartnerAssets(partnerStyleConfig?.whiteLabelStyle);
tokens = await getDesignTokens(partnerStyleConfig?.whiteLabelStyle);
}
await initializeDesignTokens(tokens);
setPartnerAssets(assets);
setDesignTokens(tokens);
};
// remove this if not using WhiteLabelParams
fetchAssetsAndTokens();
}, [params.whiteLabelStyle, partnerStyleConfig?.whiteLabelStyle]);
return (
<WhiteLabelContext.Provider value={{ partnerAssets, designTokens }}>
{children}
</WhiteLabelContext.Provider>
);
};
export default WhiteLabelContext;
</code>
import { createContext, useState, useEffect, ReactNode } from 'react';
import { useParams } from 'react-router-dom';
import useAuth from '@hooks/useAuth.tsx';
import logger from '@utils/logger';
import { DEFAULT_OHT_WHITE_LABEL_STYLE } from '@routes/SignIn';
import { designTokens } from '../tokens/oht/designTokens.ts';
import { applyDesignTokens } from '../tokens/applyDesignTokens.ts';
import defaultLogo from '@assets/OpenHealthLogo.png';
import defaultLogoSidebar from '@assets/OpenHealthLogoSidebar.png';
import defaultBackgroundBanner1 from '@assets/background-banner1.png';
import defaultBackgroundBanner2 from '@assets/background-banner2.png';
import defaultBackgroundBanner3 from '@assets/background-banner3.png';
const defaultAssets: Record<string, string> = {
logo: defaultLogo,
logoSidebar: defaultLogoSidebar,
backgroundBanner1: defaultBackgroundBanner1,
backgroundBanner2: defaultBackgroundBanner2,
backgroundBanner3: defaultBackgroundBanner3,
};
interface WhiteLabelContextProps {
partnerAssets: Record<string, any> | null;
designTokens: Record<string, any> | null;
}
const partnerAssets = import.meta.glob([
'../tokens/WhiteLabelStyle/*/assets/*.{png,jpg,jpeg,svg}',
]);
const partnerDesignTokens = import.meta.glob(
'../tokens/WhiteLabelStyle/*/designTokens.{ts,tsx,js,jsx}'
);
const colorPattern =
/^oht-(neutral-(light|gray|dark)|brand-(p|s|t)|system-(negative|danger|positive)-(p|s))-d{3}$/;
const fontFamilyPattern = /^font-oht-family-(inter)$/;
const fontSizePattern = /^oht-d{3,4}$/;
const lineHeightPattern = /^oht-d{3,4}$/;
const fontWeightPattern = /^oht-(normal|medium|semibold|bold)$/;
const spacingPattern = /^oht-d{2,4}$/;
const borderRadiusPattern = /^oht-d{2,4}$/;
const borderWidthPattern = /^oht-d{2,3}$/;
const tokenRegexMap = {
colors: colorPattern,
fontFamily: fontFamilyPattern,
fontSize: fontSizePattern,
lineHeight: lineHeightPattern,
fontWeight: fontWeightPattern,
spacing: spacingPattern,
borderRadius: borderRadiusPattern,
borderWidth: borderWidthPattern,
};
export const getPartnerAssets = async (whiteLabelStyle?: string) => {
try {
if (whiteLabelStyle && whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE) {
const files = Object.keys(partnerAssets).filter(f =>
f.includes(whiteLabelStyle)
);
const assets: Record<string, string> = {};
for (const file of files) {
const fileName = file.split('/').pop() ?? '';
const key = fileName.split('.')[0]; // e.g., 'logo', 'image1', etc.
const fileModule: any = await partnerAssets[file]();
assets[key] = fileModule.default;
}
return assets;
}
} catch (error) {
logger.error('Failed to load images and logo', error);
return defaultAssets;
}
// Return empty object if no whiteLabelStyle or files not found
return defaultAssets;
};
export const getDesignTokens = async (whiteLabelStyle?: string) => {
try {
if (whiteLabelStyle && whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE) {
const path = Object.keys(partnerDesignTokens).find(f =>
f.includes(whiteLabelStyle)
);
if (path) {
const partnerTokens: any = await partnerDesignTokens[path]();
if (partnerTokens?.designTokens) {
return partnerTokens.designTokens;
}
}
}
} catch (error) {
return designTokens;
}
// If no partner or partner file doesn't exist, use the default tokens
return designTokens;
};
const validateTokenNames = (tokens?: any): boolean => {
if (!tokens) {
return false;
}
try {
const invalidTokens: string[] = [];
Object.keys(tokens).forEach(key => {
Object.keys(tokens[key]).forEach(token => {
if (!tokenRegexMap[key].test(token)) {
invalidTokens.push(token);
}
});
});
if (invalidTokens.length > 0) {
logger.warn('Invalid tokens:', invalidTokens);
return false;
}
return true;
} catch (_err) {
logger.warn('Error validating the tokens, Invalid tokens');
return false;
}
};
export const initializeDesignTokens = async (tokens: any) => {
try {
const isValid = validateTokenNames(tokens);
if (!isValid) {
throw new Error('Invalid token names detected.');
}
if (tokens) {
applyDesignTokens(tokens);
} else {
applyDesignTokens(designTokens);
}
} catch (error) {
logger.error('Failed to load or validate tokens for partner', error);
return designTokens;
}
};
const WhiteLabelContext = createContext<WhiteLabelContextProps | undefined>(
undefined
);
export const WhiteLabelProvider = ({ children }: { children: ReactNode }) => {
const params = useParams();
const { partnerStyleConfig } = useAuth();
const [partnerAssets, setPartnerAssets] = useState<Record<
string,
any
> | null>(null);
const [designTokens, setDesignTokens] = useState<Record<string, any> | null>(
null
);
useEffect(() => {
const fetchAssetsAndTokens = async () => {
let assets = await getPartnerAssets(DEFAULT_OHT_WHITE_LABEL_STYLE);
let tokens = await getDesignTokens(DEFAULT_OHT_WHITE_LABEL_STYLE);
if (
partnerStyleConfig?.whiteLabelStyle !== DEFAULT_OHT_WHITE_LABEL_STYLE
) {
assets = await getPartnerAssets(partnerStyleConfig?.whiteLabelStyle);
tokens = await getDesignTokens(partnerStyleConfig?.whiteLabelStyle);
}
await initializeDesignTokens(tokens);
setPartnerAssets(assets);
setDesignTokens(tokens);
};
// remove this if not using WhiteLabelParams
fetchAssetsAndTokens();
}, [params.whiteLabelStyle, partnerStyleConfig?.whiteLabelStyle]);
return (
<WhiteLabelContext.Provider value={{ partnerAssets, designTokens }}>
{children}
</WhiteLabelContext.Provider>
);
};
export default WhiteLabelContext;
I am always getting the default value before it loads to the value on the partnerAssets and designTokens