@contentful/experiences-core 3.8.3 → 3.8.4-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2842,37 +2842,32 @@ const maybePopulateDesignTokenValue = (variableName, variableValue, mapOfDesignV
2842
2842
  if (!isCfStyleAttribute(variableName)) {
2843
2843
  return variableValue;
2844
2844
  }
2845
- const resolveSimpleDesignToken = (variableName, variableValue) => {
2846
- const nonTemplateDesignTokenValue = variableValue.replace(templateStringRegex, '$1');
2847
- const tokenValue = mapOfDesignVariableKeys[nonTemplateDesignTokenValue];
2848
- if (!tokenValue) {
2849
- if (builtInStyles[variableName]) {
2850
- return builtInStyles[variableName].defaultValue;
2845
+ // matches ${...} and captures the content between ${ and }
2846
+ // ${color.Blue}, ${spacing.Sizes.Large} or ${border.Text Heading.Small}
2847
+ const templateStringRegex = /\$\{(\w[^}]*)}/g;
2848
+ const result = variableValue
2849
+ .replace(templateStringRegex, (_, rawKey) => {
2850
+ const value = mapOfDesignVariableKeys[rawKey];
2851
+ if (!value) {
2852
+ if (builtInStyles[variableName]?.defaultValue) {
2853
+ return String(builtInStyles[variableName].defaultValue);
2851
2854
  }
2852
- if (optionalBuiltInStyles[variableName]) {
2853
- return optionalBuiltInStyles[variableName].defaultValue;
2855
+ if (optionalBuiltInStyles[variableName]?.defaultValue) {
2856
+ return String(optionalBuiltInStyles[variableName].defaultValue);
2854
2857
  }
2855
2858
  return '0px';
2856
2859
  }
2857
2860
  if (variableName === 'cfBorder' || variableName.startsWith('cfBorder_')) {
2858
- if (typeof tokenValue === 'object') {
2859
- const { width, style, color } = tokenValue;
2861
+ if (typeof value === 'object') {
2862
+ const { width, style, color } = value;
2860
2863
  return `${width} ${style} ${color}`;
2861
2864
  }
2862
2865
  }
2863
- return tokenValue;
2864
- };
2865
- const templateStringRegex = /\${(.+?)}/g;
2866
- const parts = variableValue.split(' ');
2867
- let resolvedValue = '';
2868
- for (const part of parts) {
2869
- const tokenValue = templateStringRegex.test(part)
2870
- ? resolveSimpleDesignToken(variableName, part)
2871
- : part;
2872
- resolvedValue += `${tokenValue} `;
2873
- }
2874
- // Not trimming would end up with a trailing space that breaks the check in `calculateNodeDefaultHeight`
2875
- return resolvedValue.trim();
2866
+ return String(value);
2867
+ })
2868
+ // Replace all multiple spaces with a single space
2869
+ .replace(/ +/g, ' ');
2870
+ return result;
2876
2871
  };
2877
2872
  const transformMedia$1 = (boundAsset, width, options) => {
2878
2873
  try {
@@ -2928,6 +2923,11 @@ const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataS
2928
2923
  // '/lUERH7tX7nJTaPX6f0udB/fields/assetReference/~locale/fields/file/~locale'
2929
2924
  const [, uuid] = variableData.path.split('/');
2930
2925
  const binding = dataSource[uuid];
2926
+ // Safeguard against edge cases - we should not have bound style values that do not have a data source entry.
2927
+ // However, just in case, we handle it here as empty and allow the user to replace without errors.
2928
+ if (!binding) {
2929
+ return;
2930
+ }
2931
2931
  const boundEntity = getBoundEntityById(binding.sys.id);
2932
2932
  if (!boundEntity) {
2933
2933
  return;
@@ -3094,18 +3094,30 @@ const indexByBreakpoint = ({ variables, breakpointIds, getBoundEntityById, unbou
3094
3094
  * `{ 'color.key': [value] }`
3095
3095
  */
3096
3096
  const flattenDesignTokenRegistry = (designTokenRegistry) => {
3097
- return Object.entries(designTokenRegistry).reduce((acc, [categoryName, tokenCategory]) => {
3098
- const tokensWithCategory = Object.entries(tokenCategory).reduce((acc, [tokenName, tokenValue]) => {
3099
- return {
3100
- ...acc,
3101
- [`${categoryName}.${tokenName}`]: tokenValue,
3102
- };
3097
+ const flattenObject = (obj, prefix = '') => {
3098
+ return Object.entries(obj).reduce((acc, [key, value]) => {
3099
+ const newKey = prefix ? `${prefix}.${key}` : key;
3100
+ if (value &&
3101
+ typeof value === 'object' &&
3102
+ !Array.isArray(value) &&
3103
+ // handle border types
3104
+ !(typeof value === 'object' && ('width' in value || 'style' in value || 'color' in value))) {
3105
+ // Recursively flatten nested objects, but skip objects that look like border definitions
3106
+ return {
3107
+ ...acc,
3108
+ ...flattenObject(value, newKey),
3109
+ };
3110
+ }
3111
+ else {
3112
+ // This is a leaf value (string, number, or border object)
3113
+ return {
3114
+ ...acc,
3115
+ [newKey]: value,
3116
+ };
3117
+ }
3103
3118
  }, {});
3104
- return {
3105
- ...acc,
3106
- ...tokensWithCategory,
3107
- };
3108
- }, {});
3119
+ };
3120
+ return flattenObject(designTokenRegistry);
3109
3121
  };
3110
3122
  function mergeDefaultAndOverwriteValues(defaultValue, overwriteValue) {
3111
3123
  if (defaultValue?.type === 'DesignValue' && overwriteValue?.type === 'DesignValue') {