@contentful/experiences-sdk-react 1.37.1 → 1.37.2-dev-20250515T1505-4c9ed48.0

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.
@@ -3,7 +3,7 @@ import React, { useMemo } from 'react';
3
3
  import { checkIsAssemblyNode, transformBoundContentValue, resolveHyperlinkPattern, sanitizeNodeProps } from '@contentful/experiences-core';
4
4
  import { HYPERLINK_DEFAULT_PATTERN, CONTENTFUL_COMPONENTS } from '@contentful/experiences-core/constants';
5
5
  import { getComponentRegistration, createAssemblyRegistration } from '../../core/componentRegistry.js';
6
- import { useInjectStylesheet } from '../../hooks/useClassName.js';
6
+ import { useInjectStylesheet } from '../../hooks/useInjectStylesheet.js';
7
7
  import { Assembly, ContentfulContainer, Columns, SingleColumn } from '@contentful/experiences-components-react';
8
8
  import { resolveAssembly } from '../../core/preview/assemblyUtils.js';
9
9
  import PreviewUnboundImage from './PreviewUnboundImage.js';
@@ -80,6 +80,7 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
80
80
  breakpoints: entityStore.breakpoints,
81
81
  mainBreakpoint,
82
82
  componentDefinition: componentRegistration.definition,
83
+ patternNodeIdsChain,
83
84
  node,
84
85
  resolveCustomDesignValue: ({ propertyName, valuesByBreakpoint }) => {
85
86
  return resolveDesignValue(valuesByBreakpoint, propertyName);
@@ -142,7 +143,7 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
142
143
  patternRootNodeIdsChain,
143
144
  ]);
144
145
  // do not inject the stylesheet into the dom because it's already been done on the server side
145
- useInjectStylesheet(ssrProps.cfSsrClassName ? undefined : mediaQuery);
146
+ useInjectStylesheet(ssrProps.cfSsrClassName ? undefined : mediaQuery?.css);
146
147
  if (!componentRegistration) {
147
148
  return null;
148
149
  }
@@ -181,7 +182,7 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
181
182
  }
182
183
  if (node.definitionId === CONTENTFUL_COMPONENTS.image.id &&
183
184
  node.variables.cfImageAsset?.type === 'UnboundValue') {
184
- return (jsx(PreviewUnboundImage, { node: node, nodeProps: props, component: component, breakpoints: entityStore.breakpoints }));
185
+ return (jsx(PreviewUnboundImage, { node: node, nodeProps: props, component: component, breakpoints: entityStore.breakpoints, patternNodeIdsChain: patternNodeIdsChain }));
185
186
  }
186
187
  return React.createElement(component, {
187
188
  ...sanitizeNodeProps(props),
@@ -1 +1 @@
1
- {"version":3,"file":"CompositionBlock.js","sources":["../../../../src/blocks/preview/CompositionBlock.tsx"],"sourcesContent":["import React, { ReactNode, useMemo } from 'react';\nimport type { UnresolvedLink } from 'contentful';\nimport {\n EntityStore,\n resolveHyperlinkPattern,\n sanitizeNodeProps,\n} from '@contentful/experiences-core';\nimport {\n CONTENTFUL_COMPONENTS,\n HYPERLINK_DEFAULT_PATTERN,\n} from '@contentful/experiences-core/constants';\nimport type {\n ComponentTreeNode,\n DesignValue,\n PatternProperty,\n PrimitiveValue,\n ResolveDesignValueType,\n StyleProps,\n} from '@contentful/experiences-core/types';\nimport { createAssemblyRegistration, getComponentRegistration } from '../../core/componentRegistry';\nimport { checkIsAssemblyNode, transformBoundContentValue } from '@contentful/experiences-core';\nimport { useInjectStylesheet } from '../../hooks/useClassName';\nimport {\n Assembly,\n Columns,\n ContentfulContainer,\n SingleColumn,\n} from '@contentful/experiences-components-react';\nimport { resolveAssembly } from '../../core/preview/assemblyUtils';\nimport { Entry } from 'contentful';\nimport PreviewUnboundImage from './PreviewUnboundImage';\nimport { parseComponentProps } from '../../utils/parseComponentProps';\n\ntype CompositionBlockProps = {\n node: ComponentTreeNode;\n locale: string;\n entityStore: EntityStore;\n hyperlinkPattern?: string | undefined;\n resolveDesignValue: ResolveDesignValueType;\n getPatternChildNodeClassName?: (childNodeId: string) => string | undefined;\n wrappingPatternIds?: Set<string>;\n /**\n * Chained IDs to ensure uniqueness across multiple instances of the same pattern\n * when storing & accessing cfSsrClassName.\n */\n patternNodeIdsChain?: string;\n patternRootNodeIdsChain?: string;\n wrappingPatternProperties?: Record<string, PatternProperty>;\n};\n\nexport const CompositionBlock = ({\n node: rawNode,\n locale,\n entityStore,\n hyperlinkPattern,\n resolveDesignValue,\n getPatternChildNodeClassName,\n wrappingPatternIds: parentWrappingPatternIds = new Set(),\n wrappingPatternProperties: parentWrappingPatternProperties = {},\n patternNodeIdsChain = '',\n patternRootNodeIdsChain: parentPatternRootNodeIdsChain = '',\n}: CompositionBlockProps) => {\n patternNodeIdsChain = `${patternNodeIdsChain}${rawNode.id}`;\n\n const isAssembly = useMemo(\n () =>\n checkIsAssemblyNode({\n componentId: rawNode.definitionId,\n usedComponents: entityStore.usedComponents,\n }),\n [entityStore.usedComponents, rawNode.definitionId],\n );\n\n const patternRootNodeIdsChain = useMemo(() => {\n if (isAssembly) {\n return `${parentPatternRootNodeIdsChain}${rawNode.id}`;\n }\n return parentPatternRootNodeIdsChain;\n }, [isAssembly, parentPatternRootNodeIdsChain, rawNode.id]);\n\n const node = useMemo(() => {\n return isAssembly\n ? resolveAssembly({\n node: rawNode,\n entityStore,\n parentPatternProperties: parentWrappingPatternProperties,\n patternNodeIdsChain: patternRootNodeIdsChain,\n })\n : rawNode;\n }, [entityStore, isAssembly, rawNode, parentWrappingPatternProperties, patternRootNodeIdsChain]);\n\n const wrappingPatternIds = useMemo(() => {\n if (isAssembly) {\n return new Set([node.definitionId, ...parentWrappingPatternIds]);\n }\n return parentWrappingPatternIds;\n }, [isAssembly, node, parentWrappingPatternIds]);\n\n // Merge the pattern properties of the current node with the parent's pattern properties\n // to ensure nested patterns receive relevant pattern properties that were bubbled up\n // during assembly serialization.\n const wrappingPatternProperties = useMemo(() => {\n if (isAssembly) {\n return { ...parentWrappingPatternProperties, ...(rawNode.patternProperties || {}) };\n }\n return parentWrappingPatternProperties;\n }, [isAssembly, rawNode, parentWrappingPatternProperties]);\n\n const componentRegistration = useMemo(() => {\n const registration = getComponentRegistration(node.definitionId as string);\n\n if (isAssembly && !registration) {\n return createAssemblyRegistration({\n definitionId: node.definitionId as string,\n component: Assembly,\n });\n }\n return registration;\n }, [isAssembly, node.definitionId]);\n\n const { ssrProps, contentProps, props, mediaQuery } = useMemo(() => {\n // In SSR, we store the className under breakpoints[0] which is resolved here to the actual string\n const cfSsrClassNameValues = node.variables.cfSsrClassName as DesignValue | undefined;\n const mainBreakpoint = entityStore.breakpoints[0];\n const cfSsrClassName = cfSsrClassNameValues?.valuesByBreakpoint?.[mainBreakpoint.id] as\n | string\n | undefined;\n\n // Don't enrich the assembly wrapper node with props\n if (!componentRegistration || isAssembly) {\n const ssrProps = { cfSsrClassName };\n const props: Record<string, PrimitiveValue> = { className: cfSsrClassName };\n return {\n ssrProps,\n props,\n customDesignProps: {},\n };\n }\n\n const ssrProps: Record<string, string | undefined> = {\n cfSsrClassName:\n node.id && getPatternChildNodeClassName\n ? getPatternChildNodeClassName(node.id)\n : cfSsrClassName,\n };\n\n const {\n contentProps = {},\n styleProps = {},\n customDesignProps = {},\n mediaQuery,\n } = parseComponentProps({\n breakpoints: entityStore.breakpoints,\n mainBreakpoint,\n componentDefinition: componentRegistration.definition,\n node,\n resolveCustomDesignValue: ({ propertyName, valuesByBreakpoint }) => {\n return resolveDesignValue(valuesByBreakpoint, propertyName);\n },\n resolveBoundValue: ({ binding, propertyName, dataType }) => {\n const [, uuid] = binding.path.split('/');\n const boundEntityLink = entityStore.dataSource[uuid] as UnresolvedLink<'Entry' | 'Asset'>;\n const boundValue = transformBoundContentValue(\n node.variables,\n entityStore,\n boundEntityLink,\n resolveDesignValue,\n propertyName,\n dataType,\n binding.path,\n );\n\n return boundValue;\n },\n resolveHyperlinkValue: ({ linkTargetKey }) => {\n const boundEntity = entityStore.dataSource[linkTargetKey];\n const hyperlinkEntry = entityStore.getEntryOrAsset(boundEntity, linkTargetKey);\n\n const value = resolveHyperlinkPattern(\n componentRegistration.definition.hyperlinkPattern ||\n hyperlinkPattern ||\n HYPERLINK_DEFAULT_PATTERN,\n hyperlinkEntry as Entry,\n locale,\n );\n\n return value;\n },\n resolveUnboundValue: ({ mappingKey, defaultValue }) => {\n return entityStore.unboundValues[mappingKey]?.value ?? defaultValue;\n },\n });\n\n const slotsProps: Record<string, ReactNode> = {};\n\n if (componentRegistration.definition.slots) {\n for (const slotId in componentRegistration.definition.slots) {\n const slotNode = node.children.find((child) => child.slotId === slotId);\n if (slotNode) {\n slotsProps[slotId] = (\n <CompositionBlock\n node={slotNode}\n locale={locale}\n hyperlinkPattern={hyperlinkPattern}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n wrappingPatternIds={wrappingPatternIds}\n wrappingPatternProperties={wrappingPatternProperties}\n patternNodeIdsChain={patternNodeIdsChain}\n patternRootNodeIdsChain={patternRootNodeIdsChain}\n />\n );\n }\n }\n }\n\n const props: Record<string, PrimitiveValue> = {\n className: ssrProps.cfSsrClassName ?? mediaQuery?.className,\n ...styleProps,\n ...contentProps,\n ...customDesignProps,\n ...slotsProps,\n };\n\n return {\n ssrProps,\n contentProps,\n slotsProps,\n styleProps,\n customDesignProps,\n mediaQuery,\n props,\n };\n }, [\n node,\n entityStore,\n componentRegistration,\n isAssembly,\n getPatternChildNodeClassName,\n resolveDesignValue,\n hyperlinkPattern,\n locale,\n wrappingPatternIds,\n wrappingPatternProperties,\n patternNodeIdsChain,\n patternRootNodeIdsChain,\n ]);\n\n // do not inject the stylesheet into the dom because it's already been done on the server side\n useInjectStylesheet(ssrProps.cfSsrClassName ? undefined : mediaQuery);\n\n if (!componentRegistration) {\n return null;\n }\n\n // When detecting a circular dependency, we stop silently. The editor mode will render an actionable error.\n if (parentWrappingPatternIds.has(node.definitionId)) {\n return null;\n }\n\n const { component } = componentRegistration;\n\n // Retrieves the CSS class name for a given child node ID.\n const _getPatternChildNodeClassName = (childNodeId: string) => {\n if (isAssembly) {\n const nodeIdsChain = `${patternNodeIdsChain}${childNodeId}`;\n // @ts-expect-error -- property cfSsrClassName is a map (id to classNames) that is added during rendering in ssrStyles\n const classesForNode: DesignValue | undefined = node.variables.cfSsrClassName?.[nodeIdsChain];\n\n if (!classesForNode) return undefined;\n return resolveDesignValue(classesForNode.valuesByBreakpoint, 'cfSsrClassName') as string;\n }\n return getPatternChildNodeClassName?.(`${node.id}${childNodeId}`);\n };\n\n const children =\n componentRegistration.definition.children === true\n ? node.children.map((childNode: ComponentTreeNode, index) => {\n return (\n <CompositionBlock\n getPatternChildNodeClassName={\n isAssembly || getPatternChildNodeClassName\n ? _getPatternChildNodeClassName\n : undefined\n }\n node={childNode}\n key={index}\n locale={locale}\n hyperlinkPattern={hyperlinkPattern}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n wrappingPatternIds={wrappingPatternIds}\n wrappingPatternProperties={wrappingPatternProperties}\n patternNodeIdsChain={patternNodeIdsChain}\n patternRootNodeIdsChain={patternRootNodeIdsChain}\n />\n );\n })\n : null;\n\n if (isContainerOrSection(node.definitionId)) {\n return (\n <ContentfulContainer\n editorMode={false}\n cfHyperlink={(contentProps as StyleProps).cfHyperlink}\n cfOpenInNewTab={(contentProps as StyleProps).cfOpenInNewTab}\n className={props.className as string | undefined}>\n {children}\n </ContentfulContainer>\n );\n }\n\n if (node.definitionId === CONTENTFUL_COMPONENTS.columns.id) {\n return (\n <Columns editorMode={false} className={props.className as string | undefined}>\n {children}\n </Columns>\n );\n }\n\n if (node.definitionId === CONTENTFUL_COMPONENTS.singleColumn.id) {\n return (\n <SingleColumn editorMode={false} className={props.className as string | undefined}>\n {children}\n </SingleColumn>\n );\n }\n\n if (\n node.definitionId === CONTENTFUL_COMPONENTS.image.id &&\n node.variables.cfImageAsset?.type === 'UnboundValue'\n ) {\n return (\n <PreviewUnboundImage\n node={node}\n nodeProps={props}\n component={component}\n breakpoints={entityStore.breakpoints}\n />\n );\n }\n\n return React.createElement(\n component,\n {\n ...sanitizeNodeProps(props),\n },\n children ?? (typeof props.children === 'string' ? props.children : null),\n );\n};\n\nconst isContainerOrSection = (\n nodeDefinitionId: string,\n): nodeDefinitionId is 'contentful-container' | 'contentful-section' =>\n [CONTENTFUL_COMPONENTS.container.id, CONTENTFUL_COMPONENTS.section.id].includes(\n nodeDefinitionId as 'contentful-container' | 'contentful-section',\n );\n"],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"CompositionBlock.js","sources":["../../../../src/blocks/preview/CompositionBlock.tsx"],"sourcesContent":["import React, { ReactNode, useMemo } from 'react';\nimport type { UnresolvedLink } from 'contentful';\nimport {\n EntityStore,\n resolveHyperlinkPattern,\n sanitizeNodeProps,\n} from '@contentful/experiences-core';\nimport {\n CONTENTFUL_COMPONENTS,\n HYPERLINK_DEFAULT_PATTERN,\n} from '@contentful/experiences-core/constants';\nimport type {\n ComponentTreeNode,\n DesignValue,\n PatternProperty,\n PrimitiveValue,\n ResolveDesignValueType,\n StyleProps,\n} from '@contentful/experiences-core/types';\nimport { createAssemblyRegistration, getComponentRegistration } from '../../core/componentRegistry';\nimport { checkIsAssemblyNode, transformBoundContentValue } from '@contentful/experiences-core';\nimport { useInjectStylesheet } from '../../hooks/useInjectStylesheet';\nimport {\n Assembly,\n Columns,\n ContentfulContainer,\n SingleColumn,\n} from '@contentful/experiences-components-react';\nimport { resolveAssembly } from '../../core/preview/assemblyUtils';\nimport { Entry } from 'contentful';\nimport PreviewUnboundImage from './PreviewUnboundImage';\nimport { parseComponentProps } from '../../utils/parseComponentProps';\n\ntype CompositionBlockProps = {\n node: ComponentTreeNode;\n locale: string;\n entityStore: EntityStore;\n hyperlinkPattern?: string | undefined;\n resolveDesignValue: ResolveDesignValueType;\n getPatternChildNodeClassName?: (childNodeId: string) => string | undefined;\n wrappingPatternIds?: Set<string>;\n /**\n * Chained IDs to ensure uniqueness across multiple instances of the same pattern\n * when storing & accessing cfSsrClassName.\n */\n patternNodeIdsChain?: string;\n patternRootNodeIdsChain?: string;\n wrappingPatternProperties?: Record<string, PatternProperty>;\n};\n\nexport const CompositionBlock = ({\n node: rawNode,\n locale,\n entityStore,\n hyperlinkPattern,\n resolveDesignValue,\n getPatternChildNodeClassName,\n wrappingPatternIds: parentWrappingPatternIds = new Set(),\n wrappingPatternProperties: parentWrappingPatternProperties = {},\n patternNodeIdsChain = '',\n patternRootNodeIdsChain: parentPatternRootNodeIdsChain = '',\n}: CompositionBlockProps) => {\n patternNodeIdsChain = `${patternNodeIdsChain}${rawNode.id}`;\n\n const isAssembly = useMemo(\n () =>\n checkIsAssemblyNode({\n componentId: rawNode.definitionId,\n usedComponents: entityStore.usedComponents,\n }),\n [entityStore.usedComponents, rawNode.definitionId],\n );\n\n const patternRootNodeIdsChain = useMemo(() => {\n if (isAssembly) {\n return `${parentPatternRootNodeIdsChain}${rawNode.id}`;\n }\n return parentPatternRootNodeIdsChain;\n }, [isAssembly, parentPatternRootNodeIdsChain, rawNode.id]);\n\n const node = useMemo(() => {\n return isAssembly\n ? resolveAssembly({\n node: rawNode,\n entityStore,\n parentPatternProperties: parentWrappingPatternProperties,\n patternNodeIdsChain: patternRootNodeIdsChain,\n })\n : rawNode;\n }, [entityStore, isAssembly, rawNode, parentWrappingPatternProperties, patternRootNodeIdsChain]);\n\n const wrappingPatternIds = useMemo(() => {\n if (isAssembly) {\n return new Set([node.definitionId, ...parentWrappingPatternIds]);\n }\n return parentWrappingPatternIds;\n }, [isAssembly, node, parentWrappingPatternIds]);\n\n // Merge the pattern properties of the current node with the parent's pattern properties\n // to ensure nested patterns receive relevant pattern properties that were bubbled up\n // during assembly serialization.\n const wrappingPatternProperties = useMemo(() => {\n if (isAssembly) {\n return { ...parentWrappingPatternProperties, ...(rawNode.patternProperties || {}) };\n }\n return parentWrappingPatternProperties;\n }, [isAssembly, rawNode, parentWrappingPatternProperties]);\n\n const componentRegistration = useMemo(() => {\n const registration = getComponentRegistration(node.definitionId as string);\n\n if (isAssembly && !registration) {\n return createAssemblyRegistration({\n definitionId: node.definitionId as string,\n component: Assembly,\n });\n }\n return registration;\n }, [isAssembly, node.definitionId]);\n\n const { ssrProps, contentProps, props, mediaQuery } = useMemo(() => {\n // In SSR, we store the className under breakpoints[0] which is resolved here to the actual string\n const cfSsrClassNameValues = node.variables.cfSsrClassName as DesignValue | undefined;\n const mainBreakpoint = entityStore.breakpoints[0];\n const cfSsrClassName = cfSsrClassNameValues?.valuesByBreakpoint?.[mainBreakpoint.id] as\n | string\n | undefined;\n\n // Don't enrich the assembly wrapper node with props\n if (!componentRegistration || isAssembly) {\n const ssrProps = { cfSsrClassName };\n const props: Record<string, PrimitiveValue> = { className: cfSsrClassName };\n return {\n ssrProps,\n props,\n customDesignProps: {},\n };\n }\n\n const ssrProps: Record<string, string | undefined> = {\n cfSsrClassName:\n node.id && getPatternChildNodeClassName\n ? getPatternChildNodeClassName(node.id)\n : cfSsrClassName,\n };\n\n const {\n contentProps = {},\n styleProps = {},\n customDesignProps = {},\n mediaQuery,\n } = parseComponentProps({\n breakpoints: entityStore.breakpoints,\n mainBreakpoint,\n componentDefinition: componentRegistration.definition,\n patternNodeIdsChain,\n node,\n resolveCustomDesignValue: ({ propertyName, valuesByBreakpoint }) => {\n return resolveDesignValue(valuesByBreakpoint, propertyName);\n },\n resolveBoundValue: ({ binding, propertyName, dataType }) => {\n const [, uuid] = binding.path.split('/');\n const boundEntityLink = entityStore.dataSource[uuid] as UnresolvedLink<'Entry' | 'Asset'>;\n const boundValue = transformBoundContentValue(\n node.variables,\n entityStore,\n boundEntityLink,\n resolveDesignValue,\n propertyName,\n dataType,\n binding.path,\n );\n\n return boundValue;\n },\n resolveHyperlinkValue: ({ linkTargetKey }) => {\n const boundEntity = entityStore.dataSource[linkTargetKey];\n const hyperlinkEntry = entityStore.getEntryOrAsset(boundEntity, linkTargetKey);\n\n const value = resolveHyperlinkPattern(\n componentRegistration.definition.hyperlinkPattern ||\n hyperlinkPattern ||\n HYPERLINK_DEFAULT_PATTERN,\n hyperlinkEntry as Entry,\n locale,\n );\n\n return value;\n },\n resolveUnboundValue: ({ mappingKey, defaultValue }) => {\n return entityStore.unboundValues[mappingKey]?.value ?? defaultValue;\n },\n });\n\n const slotsProps: Record<string, ReactNode> = {};\n\n if (componentRegistration.definition.slots) {\n for (const slotId in componentRegistration.definition.slots) {\n const slotNode = node.children.find((child) => child.slotId === slotId);\n if (slotNode) {\n slotsProps[slotId] = (\n <CompositionBlock\n node={slotNode}\n locale={locale}\n hyperlinkPattern={hyperlinkPattern}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n wrappingPatternIds={wrappingPatternIds}\n wrappingPatternProperties={wrappingPatternProperties}\n patternNodeIdsChain={patternNodeIdsChain}\n patternRootNodeIdsChain={patternRootNodeIdsChain}\n />\n );\n }\n }\n }\n\n const props: Record<string, PrimitiveValue> = {\n className: ssrProps.cfSsrClassName ?? mediaQuery?.className,\n ...styleProps,\n ...contentProps,\n ...customDesignProps,\n ...slotsProps,\n };\n\n return {\n ssrProps,\n contentProps,\n slotsProps,\n styleProps,\n customDesignProps,\n mediaQuery,\n props,\n };\n }, [\n node,\n entityStore,\n componentRegistration,\n isAssembly,\n getPatternChildNodeClassName,\n resolveDesignValue,\n hyperlinkPattern,\n locale,\n wrappingPatternIds,\n wrappingPatternProperties,\n patternNodeIdsChain,\n patternRootNodeIdsChain,\n ]);\n\n // do not inject the stylesheet into the dom because it's already been done on the server side\n useInjectStylesheet(ssrProps.cfSsrClassName ? undefined : mediaQuery?.css);\n\n if (!componentRegistration) {\n return null;\n }\n\n // When detecting a circular dependency, we stop silently. The editor mode will render an actionable error.\n if (parentWrappingPatternIds.has(node.definitionId)) {\n return null;\n }\n\n const { component } = componentRegistration;\n\n // Retrieves the CSS class name for a given child node ID.\n const _getPatternChildNodeClassName = (childNodeId: string) => {\n if (isAssembly) {\n const nodeIdsChain = `${patternNodeIdsChain}${childNodeId}`;\n // @ts-expect-error -- property cfSsrClassName is a map (id to classNames) that is added during rendering in ssrStyles\n const classesForNode: DesignValue | undefined = node.variables.cfSsrClassName?.[nodeIdsChain];\n\n if (!classesForNode) return undefined;\n return resolveDesignValue(classesForNode.valuesByBreakpoint, 'cfSsrClassName') as string;\n }\n return getPatternChildNodeClassName?.(`${node.id}${childNodeId}`);\n };\n\n const children =\n componentRegistration.definition.children === true\n ? node.children.map((childNode: ComponentTreeNode, index) => {\n return (\n <CompositionBlock\n getPatternChildNodeClassName={\n isAssembly || getPatternChildNodeClassName\n ? _getPatternChildNodeClassName\n : undefined\n }\n node={childNode}\n key={index}\n locale={locale}\n hyperlinkPattern={hyperlinkPattern}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n wrappingPatternIds={wrappingPatternIds}\n wrappingPatternProperties={wrappingPatternProperties}\n patternNodeIdsChain={patternNodeIdsChain}\n patternRootNodeIdsChain={patternRootNodeIdsChain}\n />\n );\n })\n : null;\n\n if (isContainerOrSection(node.definitionId)) {\n return (\n <ContentfulContainer\n editorMode={false}\n cfHyperlink={(contentProps as StyleProps).cfHyperlink}\n cfOpenInNewTab={(contentProps as StyleProps).cfOpenInNewTab}\n className={props.className as string | undefined}>\n {children}\n </ContentfulContainer>\n );\n }\n\n if (node.definitionId === CONTENTFUL_COMPONENTS.columns.id) {\n return (\n <Columns editorMode={false} className={props.className as string | undefined}>\n {children}\n </Columns>\n );\n }\n\n if (node.definitionId === CONTENTFUL_COMPONENTS.singleColumn.id) {\n return (\n <SingleColumn editorMode={false} className={props.className as string | undefined}>\n {children}\n </SingleColumn>\n );\n }\n\n if (\n node.definitionId === CONTENTFUL_COMPONENTS.image.id &&\n node.variables.cfImageAsset?.type === 'UnboundValue'\n ) {\n return (\n <PreviewUnboundImage\n node={node}\n nodeProps={props}\n component={component}\n breakpoints={entityStore.breakpoints}\n patternNodeIdsChain={patternNodeIdsChain}\n />\n );\n }\n\n return React.createElement(\n component,\n {\n ...sanitizeNodeProps(props),\n },\n children ?? (typeof props.children === 'string' ? props.children : null),\n );\n};\n\nconst isContainerOrSection = (\n nodeDefinitionId: string,\n): nodeDefinitionId is 'contentful-container' | 'contentful-section' =>\n [CONTENTFUL_COMPONENTS.container.id, CONTENTFUL_COMPONENTS.section.id].includes(\n nodeDefinitionId as 'contentful-container' | 'contentful-section',\n );\n"],"names":["_jsx"],"mappings":"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"}
@@ -2,14 +2,14 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import React, { useMemo } from 'react';
3
3
  import { sanitizeNodeProps } from '@contentful/experiences-core';
4
4
  import { useMediaQuery } from '../../hooks/useMediaQuery.js';
5
- import { useInjectStylesheet } from '../../hooks/useClassName.js';
5
+ import { useInjectStylesheet } from '../../hooks/useInjectStylesheet.js';
6
6
  import classNames from 'classnames';
7
7
 
8
8
  /**
9
9
  * This component is used to render a placeholder Image component in the preview
10
10
  * when the image is unbound. It applies the Image size styles to a wrapping div.
11
11
  */
12
- const PreviewUnboundImage = ({ breakpoints, node, nodeProps, component, }) => {
12
+ const PreviewUnboundImage = ({ breakpoints, node, nodeProps, component, patternNodeIdsChain, }) => {
13
13
  const { wrapperStyle, imageStyle } = useMemo(() => {
14
14
  const imageStyle = {};
15
15
  const wrapperStyle = {};
@@ -34,14 +34,16 @@ const PreviewUnboundImage = ({ breakpoints, node, nodeProps, component, }) => {
34
34
  designPropertiesByBreakpoint: wrapperStyle,
35
35
  node,
36
36
  breakpoints,
37
+ patternNodeIdsChain,
37
38
  });
38
39
  const imageMedia = useMediaQuery({
39
40
  designPropertiesByBreakpoint: imageStyle,
40
41
  node,
41
42
  breakpoints,
43
+ patternNodeIdsChain,
42
44
  });
43
- useInjectStylesheet(wrapperMedia);
44
- useInjectStylesheet(imageMedia);
45
+ useInjectStylesheet(wrapperMedia.css);
46
+ useInjectStylesheet(imageMedia.css);
45
47
  return (jsx("div", { className: classNames('cf-preview-unbound-image', wrapperMedia.className), children: React.createElement(component, {
46
48
  ...sanitizeNodeProps(nodeProps),
47
49
  className: classNames(nodeProps.className, imageMedia.className),
@@ -1 +1 @@
1
- {"version":3,"file":"PreviewUnboundImage.js","sources":["../../../../src/blocks/preview/PreviewUnboundImage.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport type {\n Breakpoint,\n ComponentTreeNode,\n PrimitiveValue,\n} from '@contentful/experiences-core/types';\nimport { sanitizeNodeProps } from '@contentful/experiences-core';\nimport { useMediaQuery } from '../../hooks/useMediaQuery';\nimport { useInjectStylesheet } from '../../hooks/useClassName';\nimport classNames from 'classnames';\n\ninterface PreviewUnboundImageProps {\n breakpoints: Breakpoint[];\n node: ComponentTreeNode;\n nodeProps: Record<PropertyKey, PrimitiveValue>;\n component: React.ElementType;\n}\n\n/**\n * This component is used to render a placeholder Image component in the preview\n * when the image is unbound. It applies the Image size styles to a wrapping div.\n */\nconst PreviewUnboundImage: React.FC<PreviewUnboundImageProps> = ({\n breakpoints,\n node,\n nodeProps,\n component,\n}) => {\n const { wrapperStyle, imageStyle } = useMemo(() => {\n const imageStyle: Record<string, any> = {};\n const wrapperStyle: Record<string, any> = {};\n\n if (nodeProps.cfImageOptions && typeof nodeProps.cfImageOptions === 'object') {\n for (const [breakpointId, styles] of Object.entries(nodeProps.cfImageOptions)) {\n imageStyle[breakpointId] = {\n cfImageOptions: {\n ...styles,\n height: '100%',\n width: '100%',\n },\n };\n\n wrapperStyle[breakpointId] = {\n cfHeight: styles.height,\n cfWidth: styles.width,\n };\n }\n }\n\n return { imageStyle, wrapperStyle };\n }, [nodeProps.cfImageOptions]);\n\n const wrapperMedia = useMediaQuery({\n designPropertiesByBreakpoint: wrapperStyle,\n node,\n breakpoints,\n });\n\n const imageMedia = useMediaQuery({\n designPropertiesByBreakpoint: imageStyle,\n node,\n breakpoints,\n });\n\n useInjectStylesheet(wrapperMedia);\n useInjectStylesheet(imageMedia);\n\n return (\n <div className={classNames('cf-preview-unbound-image', wrapperMedia.className)}>\n {React.createElement(component, {\n ...sanitizeNodeProps(nodeProps),\n className: classNames(nodeProps.className, imageMedia.className),\n })}\n </div>\n );\n};\n\nexport default PreviewUnboundImage;\n"],"names":["_jsx"],"mappings":";;;;;;;AAkBA;;;AAGG;AACH,MAAM,mBAAmB,GAAuC,CAAC,EAC/D,WAAW,EACX,IAAI,EACJ,SAAS,EACT,SAAS,GACV,KAAI;IACH,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAK;QAChD,MAAM,UAAU,GAAwB,EAAE,CAAC;QAC3C,MAAM,YAAY,GAAwB,EAAE,CAAC;QAE7C,IAAI,SAAS,CAAC,cAAc,IAAI,OAAO,SAAS,CAAC,cAAc,KAAK,QAAQ,EAAE;AAC5E,YAAA,KAAK,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE;gBAC7E,UAAU,CAAC,YAAY,CAAC,GAAG;AACzB,oBAAA,cAAc,EAAE;AACd,wBAAA,GAAG,MAAM;AACT,wBAAA,MAAM,EAAE,MAAM;AACd,wBAAA,KAAK,EAAE,MAAM;AACd,qBAAA;iBACF,CAAC;gBAEF,YAAY,CAAC,YAAY,CAAC,GAAG;oBAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM;oBACvB,OAAO,EAAE,MAAM,CAAC,KAAK;iBACtB,CAAC;aACH;SACF;AAED,QAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACtC,KAAC,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;IAE/B,MAAM,YAAY,GAAG,aAAa,CAAC;AACjC,QAAA,4BAA4B,EAAE,YAAY;QAC1C,IAAI;QACJ,WAAW;AACZ,KAAA,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,aAAa,CAAC;AAC/B,QAAA,4BAA4B,EAAE,UAAU;QACxC,IAAI;QACJ,WAAW;AACZ,KAAA,CAAC,CAAC;IAEH,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAClC,mBAAmB,CAAC,UAAU,CAAC,CAAC;AAEhC,IAAA,QACEA,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,UAAU,CAAC,0BAA0B,EAAE,YAAY,CAAC,SAAS,CAAC,EAC3E,QAAA,EAAA,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE;YAC9B,GAAG,iBAAiB,CAAC,SAAS,CAAC;YAC/B,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC;SACjE,CAAC,EAAA,CACE,EACN;AACJ;;;;"}
1
+ {"version":3,"file":"PreviewUnboundImage.js","sources":["../../../../src/blocks/preview/PreviewUnboundImage.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport type {\n Breakpoint,\n ComponentTreeNode,\n PrimitiveValue,\n} from '@contentful/experiences-core/types';\nimport { sanitizeNodeProps } from '@contentful/experiences-core';\nimport { useMediaQuery } from '../../hooks/useMediaQuery';\nimport { useInjectStylesheet } from '../../hooks/useInjectStylesheet';\nimport classNames from 'classnames';\n\ntype PreviewUnboundImageProps = {\n breakpoints: Breakpoint[];\n node: ComponentTreeNode;\n nodeProps: Record<PropertyKey, PrimitiveValue>;\n component: React.ElementType;\n patternNodeIdsChain: string;\n};\n\n/**\n * This component is used to render a placeholder Image component in the preview\n * when the image is unbound. It applies the Image size styles to a wrapping div.\n */\nconst PreviewUnboundImage: React.FC<PreviewUnboundImageProps> = ({\n breakpoints,\n node,\n nodeProps,\n component,\n patternNodeIdsChain,\n}) => {\n const { wrapperStyle, imageStyle } = useMemo(() => {\n const imageStyle: Record<string, any> = {};\n const wrapperStyle: Record<string, any> = {};\n\n if (nodeProps.cfImageOptions && typeof nodeProps.cfImageOptions === 'object') {\n for (const [breakpointId, styles] of Object.entries(nodeProps.cfImageOptions)) {\n imageStyle[breakpointId] = {\n cfImageOptions: {\n ...styles,\n height: '100%',\n width: '100%',\n },\n };\n\n wrapperStyle[breakpointId] = {\n cfHeight: styles.height,\n cfWidth: styles.width,\n };\n }\n }\n\n return { imageStyle, wrapperStyle };\n }, [nodeProps.cfImageOptions]);\n\n const wrapperMedia = useMediaQuery({\n designPropertiesByBreakpoint: wrapperStyle,\n node,\n breakpoints,\n patternNodeIdsChain,\n });\n\n const imageMedia = useMediaQuery({\n designPropertiesByBreakpoint: imageStyle,\n node,\n breakpoints,\n patternNodeIdsChain,\n });\n\n useInjectStylesheet(wrapperMedia.css);\n useInjectStylesheet(imageMedia.css);\n\n return (\n <div className={classNames('cf-preview-unbound-image', wrapperMedia.className)}>\n {React.createElement(component, {\n ...sanitizeNodeProps(nodeProps),\n className: classNames(nodeProps.className, imageMedia.className),\n })}\n </div>\n );\n};\n\nexport default PreviewUnboundImage;\n"],"names":["_jsx"],"mappings":";;;;;;;AAmBA;;;AAGG;AACH,MAAM,mBAAmB,GAAuC,CAAC,EAC/D,WAAW,EACX,IAAI,EACJ,SAAS,EACT,SAAS,EACT,mBAAmB,GACpB,KAAI;IACH,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAK;QAChD,MAAM,UAAU,GAAwB,EAAE,CAAC;QAC3C,MAAM,YAAY,GAAwB,EAAE,CAAC;QAE7C,IAAI,SAAS,CAAC,cAAc,IAAI,OAAO,SAAS,CAAC,cAAc,KAAK,QAAQ,EAAE;AAC5E,YAAA,KAAK,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE;gBAC7E,UAAU,CAAC,YAAY,CAAC,GAAG;AACzB,oBAAA,cAAc,EAAE;AACd,wBAAA,GAAG,MAAM;AACT,wBAAA,MAAM,EAAE,MAAM;AACd,wBAAA,KAAK,EAAE,MAAM;AACd,qBAAA;iBACF,CAAC;gBAEF,YAAY,CAAC,YAAY,CAAC,GAAG;oBAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM;oBACvB,OAAO,EAAE,MAAM,CAAC,KAAK;iBACtB,CAAC;aACH;SACF;AAED,QAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACtC,KAAC,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;IAE/B,MAAM,YAAY,GAAG,aAAa,CAAC;AACjC,QAAA,4BAA4B,EAAE,YAAY;QAC1C,IAAI;QACJ,WAAW;QACX,mBAAmB;AACpB,KAAA,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,aAAa,CAAC;AAC/B,QAAA,4BAA4B,EAAE,UAAU;QACxC,IAAI;QACJ,WAAW;QACX,mBAAmB;AACpB,KAAA,CAAC,CAAC;AAEH,IAAA,mBAAmB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AACtC,IAAA,mBAAmB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAEpC,IAAA,QACEA,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,UAAU,CAAC,0BAA0B,EAAE,YAAY,CAAC,SAAS,CAAC,EAC3E,QAAA,EAAA,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE;YAC9B,GAAG,iBAAiB,CAAC,SAAS,CAAC;YAC/B,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC;SACjE,CAAC,EAAA,CACE,EACN;AACJ;;;;"}
@@ -1,4 +1,3 @@
1
- import { checkIsAssemblyNode } from '@contentful/experiences-core';
2
1
  import md5 from 'md5';
3
2
  import { shouldUsePrebinding, resolvePrebindingPath } from '../../utils/prebindingUtils.js';
4
3
  import { PATTERN_PROPERTY_DIVIDER } from '@contentful/experiences-core/constants';
@@ -88,13 +87,6 @@ const deserializeAssemblyNode = ({ node, componentInstanceVariables, componentSe
88
87
  };
89
88
  };
90
89
  const resolveAssembly = ({ node, parentPatternProperties, patternNodeIdsChain, entityStore, }) => {
91
- const isAssembly = checkIsAssemblyNode({
92
- componentId: node.definitionId,
93
- usedComponents: entityStore.usedComponents,
94
- });
95
- if (!isAssembly) {
96
- return node;
97
- }
98
90
  const componentId = node.definitionId;
99
91
  const assembly = entityStore.usedComponents?.find((component) => component.sys.id === componentId);
100
92
  if (!assembly || !('fields' in assembly)) {
@@ -1 +1 @@
1
- {"version":3,"file":"assemblyUtils.js","sources":["../../../../src/core/preview/assemblyUtils.ts"],"sourcesContent":["import { checkIsAssemblyNode, EntityStore } from '@contentful/experiences-core';\nimport md5 from 'md5';\nimport type {\n ComponentPropertyValue,\n ComponentTreeNode,\n DesignValue,\n ExperienceComponentSettings,\n PatternProperty,\n} from '@contentful/experiences-core/types';\nimport { resolvePrebindingPath, shouldUsePrebinding } from '../../utils/prebindingUtils';\nimport { PATTERN_PROPERTY_DIVIDER } from '@contentful/experiences-core/constants';\n\n/** While unfolding the assembly definition on the instance, this function will replace all\n * ComponentValue in the definitions tree with the actual value on the instance. */\nexport const deserializeAssemblyNode = ({\n node,\n componentInstanceVariables,\n componentSettings,\n patternProperties,\n}: {\n node: ComponentTreeNode;\n componentInstanceVariables: ComponentTreeNode['variables'];\n componentSettings: ExperienceComponentSettings;\n patternProperties: Record<string, PatternProperty>;\n}): ComponentTreeNode => {\n const variables: Record<string, ComponentPropertyValue> = {};\n\n for (const [variableName, variable] of Object.entries(node.variables)) {\n variables[variableName] = variable;\n if (variable.type === 'ComponentValue') {\n const componentValueKey = variable.key;\n const instanceProperty = componentInstanceVariables[componentValueKey];\n const variableDefinition = componentSettings.variableDefinitions?.[componentValueKey];\n const defaultValue = variableDefinition?.defaultValue;\n\n const usePrebinding = shouldUsePrebinding({\n componentSettings,\n componentValueKey,\n patternProperties,\n variable: instanceProperty,\n });\n const path = resolvePrebindingPath({\n componentSettings,\n componentValueKey,\n patternProperties,\n });\n\n if (usePrebinding && path) {\n variables[variableName] = {\n type: 'BoundValue',\n path,\n };\n\n // For assembly, we look up the variable in the assembly instance and\n // replace the ComponentValue with that one.\n } else if (instanceProperty?.type === 'UnboundValue') {\n variables[variableName] = {\n type: 'UnboundValue',\n key: instanceProperty.key,\n };\n } else if (instanceProperty?.type === 'NoValue') {\n variables[variableName] = instanceProperty;\n } else if (instanceProperty?.type === 'BoundValue') {\n variables[variableName] = {\n type: 'BoundValue',\n path: instanceProperty.path,\n };\n } else if (instanceProperty?.type === 'HyperlinkValue') {\n variables[variableName] = {\n type: 'HyperlinkValue',\n linkTargetKey: instanceProperty.linkTargetKey,\n };\n } else if (instanceProperty?.type === 'DesignValue') {\n variables[variableName] = {\n type: 'DesignValue',\n valuesByBreakpoint: instanceProperty.valuesByBreakpoint,\n };\n } else if (!instanceProperty && defaultValue) {\n // So far, we only automatically fallback to the defaultValue for design properties\n if (variableDefinition.group === 'style') {\n variables[variableName] = {\n type: 'DesignValue',\n valuesByBreakpoint: (defaultValue as DesignValue).valuesByBreakpoint,\n };\n }\n }\n }\n }\n\n const children: ComponentTreeNode[] = node.children.map((child) =>\n deserializeAssemblyNode({\n node: child,\n componentInstanceVariables,\n componentSettings,\n patternProperties,\n }),\n );\n\n return {\n definitionId: node.definitionId,\n id: node.id,\n variables,\n children,\n slotId: node.slotId,\n displayName: node.displayName,\n patternProperties: node.patternProperties,\n };\n};\n\nexport const resolveAssembly = ({\n node,\n parentPatternProperties,\n patternNodeIdsChain,\n entityStore,\n}: {\n node: ComponentTreeNode;\n entityStore: EntityStore;\n parentPatternProperties: Record<string, PatternProperty>;\n patternNodeIdsChain: string;\n}) => {\n const isAssembly = checkIsAssemblyNode({\n componentId: node.definitionId,\n usedComponents: entityStore.usedComponents,\n });\n\n if (!isAssembly) {\n return node;\n }\n\n const componentId = node.definitionId as string;\n const assembly = entityStore.usedComponents?.find(\n (component) => component.sys.id === componentId,\n );\n\n if (!assembly || !('fields' in assembly)) {\n return node;\n }\n\n const patternProperties: Record<string, PatternProperty> = {};\n\n const allPatternProperties = {\n ...parentPatternProperties,\n ...(node.patternProperties || {}),\n };\n\n for (const [patternPropertyKey, patternProperty] of Object.entries(allPatternProperties)) {\n /**\n * Bubbled up pattern properties are a concatenation of the node id\n * and the pattern property definition id. We need to split them so\n * that the node only uses the pattern property definition id.\n */\n const [hashKey, patternPropertyDefinitionId] =\n patternPropertyKey.split(PATTERN_PROPERTY_DIVIDER);\n\n const hashedNodeChain = md5(patternNodeIdsChain || '');\n\n const isMatchingNode = hashKey === hashedNodeChain;\n\n if (!isMatchingNode) continue;\n\n patternProperties[patternPropertyDefinitionId] = patternProperty;\n }\n\n const componentFields = assembly.fields;\n\n const deserializedNode = deserializeAssemblyNode({\n node: {\n definitionId: node.definitionId,\n id: node.id,\n variables: node.variables,\n children: componentFields.componentTree.children,\n patternProperties,\n },\n componentInstanceVariables: node.variables,\n componentSettings: componentFields.componentSettings!,\n patternProperties,\n });\n\n entityStore.addAssemblyUnboundValues(componentFields.unboundValues);\n\n return deserializedNode;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assemblyUtils.js","sources":["../../../../src/core/preview/assemblyUtils.ts"],"sourcesContent":["import { EntityStore } from '@contentful/experiences-core';\nimport md5 from 'md5';\nimport type {\n ComponentPropertyValue,\n ComponentTreeNode,\n DesignValue,\n ExperienceComponentSettings,\n PatternProperty,\n} from '@contentful/experiences-core/types';\nimport { resolvePrebindingPath, shouldUsePrebinding } from '../../utils/prebindingUtils';\nimport { PATTERN_PROPERTY_DIVIDER } from '@contentful/experiences-core/constants';\n\n/** While unfolding the assembly definition on the instance, this function will replace all\n * ComponentValue in the definitions tree with the actual value on the instance. */\nexport const deserializeAssemblyNode = ({\n node,\n componentInstanceVariables,\n componentSettings,\n patternProperties,\n}: {\n node: ComponentTreeNode;\n componentInstanceVariables: ComponentTreeNode['variables'];\n componentSettings: ExperienceComponentSettings;\n patternProperties: Record<string, PatternProperty>;\n}): ComponentTreeNode => {\n const variables: Record<string, ComponentPropertyValue> = {};\n\n for (const [variableName, variable] of Object.entries(node.variables)) {\n variables[variableName] = variable;\n if (variable.type === 'ComponentValue') {\n const componentValueKey = variable.key;\n const instanceProperty = componentInstanceVariables[componentValueKey];\n const variableDefinition = componentSettings.variableDefinitions?.[componentValueKey];\n const defaultValue = variableDefinition?.defaultValue;\n\n const usePrebinding = shouldUsePrebinding({\n componentSettings,\n componentValueKey,\n patternProperties,\n variable: instanceProperty,\n });\n const path = resolvePrebindingPath({\n componentSettings,\n componentValueKey,\n patternProperties,\n });\n\n if (usePrebinding && path) {\n variables[variableName] = {\n type: 'BoundValue',\n path,\n };\n\n // For assembly, we look up the variable in the assembly instance and\n // replace the ComponentValue with that one.\n } else if (instanceProperty?.type === 'UnboundValue') {\n variables[variableName] = {\n type: 'UnboundValue',\n key: instanceProperty.key,\n };\n } else if (instanceProperty?.type === 'NoValue') {\n variables[variableName] = instanceProperty;\n } else if (instanceProperty?.type === 'BoundValue') {\n variables[variableName] = {\n type: 'BoundValue',\n path: instanceProperty.path,\n };\n } else if (instanceProperty?.type === 'HyperlinkValue') {\n variables[variableName] = {\n type: 'HyperlinkValue',\n linkTargetKey: instanceProperty.linkTargetKey,\n };\n } else if (instanceProperty?.type === 'DesignValue') {\n variables[variableName] = {\n type: 'DesignValue',\n valuesByBreakpoint: instanceProperty.valuesByBreakpoint,\n };\n } else if (!instanceProperty && defaultValue) {\n // So far, we only automatically fallback to the defaultValue for design properties\n if (variableDefinition.group === 'style') {\n variables[variableName] = {\n type: 'DesignValue',\n valuesByBreakpoint: (defaultValue as DesignValue).valuesByBreakpoint,\n };\n }\n }\n }\n }\n\n const children: ComponentTreeNode[] = node.children.map((child) =>\n deserializeAssemblyNode({\n node: child,\n componentInstanceVariables,\n componentSettings,\n patternProperties,\n }),\n );\n\n return {\n definitionId: node.definitionId,\n id: node.id,\n variables,\n children,\n slotId: node.slotId,\n displayName: node.displayName,\n patternProperties: node.patternProperties,\n };\n};\n\nexport const resolveAssembly = ({\n node,\n parentPatternProperties,\n patternNodeIdsChain,\n entityStore,\n}: {\n node: ComponentTreeNode;\n entityStore: EntityStore;\n parentPatternProperties: Record<string, PatternProperty>;\n patternNodeIdsChain: string;\n}) => {\n const componentId = node.definitionId as string;\n const assembly = entityStore.usedComponents?.find(\n (component) => component.sys.id === componentId,\n );\n\n if (!assembly || !('fields' in assembly)) {\n return node;\n }\n\n const patternProperties: Record<string, PatternProperty> = {};\n\n const allPatternProperties = {\n ...parentPatternProperties,\n ...(node.patternProperties || {}),\n };\n\n for (const [patternPropertyKey, patternProperty] of Object.entries(allPatternProperties)) {\n /**\n * Bubbled up pattern properties are a concatenation of the node id\n * and the pattern property definition id. We need to split them so\n * that the node only uses the pattern property definition id.\n */\n const [hashKey, patternPropertyDefinitionId] =\n patternPropertyKey.split(PATTERN_PROPERTY_DIVIDER);\n\n const hashedNodeChain = md5(patternNodeIdsChain || '');\n\n const isMatchingNode = hashKey === hashedNodeChain;\n\n if (!isMatchingNode) continue;\n\n patternProperties[patternPropertyDefinitionId] = patternProperty;\n }\n\n const componentFields = assembly.fields;\n\n const deserializedNode = deserializeAssemblyNode({\n node: {\n definitionId: node.definitionId,\n id: node.id,\n variables: node.variables,\n children: componentFields.componentTree.children,\n patternProperties,\n },\n componentInstanceVariables: node.variables,\n componentSettings: componentFields.componentSettings!,\n patternProperties,\n });\n\n entityStore.addAssemblyUnboundValues(componentFields.unboundValues);\n\n return deserializedNode;\n};\n"],"names":[],"mappings":";;;;AAYA;AACmF;AAC5E,MAAM,uBAAuB,GAAG,CAAC,EACtC,IAAI,EACJ,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,GAMlB,KAAuB;IACtB,MAAM,SAAS,GAA2C,EAAE,CAAC;AAE7D,IAAA,KAAK,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AACrE,QAAA,SAAS,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;AACnC,QAAA,IAAI,QAAQ,CAAC,IAAI,KAAK,gBAAgB,EAAE;AACtC,YAAA,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC;AACvC,YAAA,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,iBAAiB,CAAC,CAAC;YACvE,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,mBAAmB,GAAG,iBAAiB,CAAC,CAAC;AACtF,YAAA,MAAM,YAAY,GAAG,kBAAkB,EAAE,YAAY,CAAC;YAEtD,MAAM,aAAa,GAAG,mBAAmB,CAAC;gBACxC,iBAAiB;gBACjB,iBAAiB;gBACjB,iBAAiB;AACjB,gBAAA,QAAQ,EAAE,gBAAgB;AAC3B,aAAA,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,qBAAqB,CAAC;gBACjC,iBAAiB;gBACjB,iBAAiB;gBACjB,iBAAiB;AAClB,aAAA,CAAC,CAAC;AAEH,YAAA,IAAI,aAAa,IAAI,IAAI,EAAE;gBACzB,SAAS,CAAC,YAAY,CAAC,GAAG;AACxB,oBAAA,IAAI,EAAE,YAAY;oBAClB,IAAI;iBACL,CAAC;;;aAIH;AAAM,iBAAA,IAAI,gBAAgB,EAAE,IAAI,KAAK,cAAc,EAAE;gBACpD,SAAS,CAAC,YAAY,CAAC,GAAG;AACxB,oBAAA,IAAI,EAAE,cAAc;oBACpB,GAAG,EAAE,gBAAgB,CAAC,GAAG;iBAC1B,CAAC;aACH;AAAM,iBAAA,IAAI,gBAAgB,EAAE,IAAI,KAAK,SAAS,EAAE;AAC/C,gBAAA,SAAS,CAAC,YAAY,CAAC,GAAG,gBAAgB,CAAC;aAC5C;AAAM,iBAAA,IAAI,gBAAgB,EAAE,IAAI,KAAK,YAAY,EAAE;gBAClD,SAAS,CAAC,YAAY,CAAC,GAAG;AACxB,oBAAA,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,gBAAgB,CAAC,IAAI;iBAC5B,CAAC;aACH;AAAM,iBAAA,IAAI,gBAAgB,EAAE,IAAI,KAAK,gBAAgB,EAAE;gBACtD,SAAS,CAAC,YAAY,CAAC,GAAG;AACxB,oBAAA,IAAI,EAAE,gBAAgB;oBACtB,aAAa,EAAE,gBAAgB,CAAC,aAAa;iBAC9C,CAAC;aACH;AAAM,iBAAA,IAAI,gBAAgB,EAAE,IAAI,KAAK,aAAa,EAAE;gBACnD,SAAS,CAAC,YAAY,CAAC,GAAG;AACxB,oBAAA,IAAI,EAAE,aAAa;oBACnB,kBAAkB,EAAE,gBAAgB,CAAC,kBAAkB;iBACxD,CAAC;aACH;AAAM,iBAAA,IAAI,CAAC,gBAAgB,IAAI,YAAY,EAAE;;AAE5C,gBAAA,IAAI,kBAAkB,CAAC,KAAK,KAAK,OAAO,EAAE;oBACxC,SAAS,CAAC,YAAY,CAAC,GAAG;AACxB,wBAAA,IAAI,EAAE,aAAa;wBACnB,kBAAkB,EAAG,YAA4B,CAAC,kBAAkB;qBACrE,CAAC;iBACH;aACF;SACF;KACF;AAED,IAAA,MAAM,QAAQ,GAAwB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,KAC5D,uBAAuB,CAAC;AACtB,QAAA,IAAI,EAAE,KAAK;QACX,0BAA0B;QAC1B,iBAAiB;QACjB,iBAAiB;AAClB,KAAA,CAAC,CACH,CAAC;IAEF,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,SAAS;QACT,QAAQ;QACR,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;KAC1C,CAAC;AACJ,EAAE;AAEK,MAAM,eAAe,GAAG,CAAC,EAC9B,IAAI,EACJ,uBAAuB,EACvB,mBAAmB,EACnB,WAAW,GAMZ,KAAI;AACH,IAAA,MAAM,WAAW,GAAG,IAAI,CAAC,YAAsB,CAAC;IAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,EAAE,IAAI,CAC/C,CAAC,SAAS,KAAK,SAAS,CAAC,GAAG,CAAC,EAAE,KAAK,WAAW,CAChD,CAAC;IAEF,IAAI,CAAC,QAAQ,IAAI,EAAE,QAAQ,IAAI,QAAQ,CAAC,EAAE;AACxC,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,iBAAiB,GAAoC,EAAE,CAAC;AAE9D,IAAA,MAAM,oBAAoB,GAAG;AAC3B,QAAA,GAAG,uBAAuB;AAC1B,QAAA,IAAI,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC;KAClC,CAAC;AAEF,IAAA,KAAK,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;AACxF;;;;AAIG;AACH,QAAA,MAAM,CAAC,OAAO,EAAE,2BAA2B,CAAC,GAC1C,kBAAkB,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAErD,MAAM,eAAe,GAAG,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;AAEvD,QAAA,MAAM,cAAc,GAAG,OAAO,KAAK,eAAe,CAAC;AAEnD,QAAA,IAAI,CAAC,cAAc;YAAE,SAAS;AAE9B,QAAA,iBAAiB,CAAC,2BAA2B,CAAC,GAAG,eAAe,CAAC;KAClE;AAED,IAAA,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC;IAExC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAC/C,QAAA,IAAI,EAAE;YACJ,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,IAAI,CAAC,SAAS;AACzB,YAAA,QAAQ,EAAE,eAAe,CAAC,aAAa,CAAC,QAAQ;YAChD,iBAAiB;AAClB,SAAA;QACD,0BAA0B,EAAE,IAAI,CAAC,SAAS;QAC1C,iBAAiB,EAAE,eAAe,CAAC,iBAAkB;QACrD,iBAAiB;AAClB,KAAA,CAAC,CAAC;AAEH,IAAA,WAAW,CAAC,wBAAwB,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;AAEpE,IAAA,OAAO,gBAAgB,CAAC;AAC1B;;;;"}
@@ -1,19 +1,26 @@
1
1
  import { useInsertionEffect } from 'react';
2
- import '@contentful/experiences-core';
3
2
 
4
- const useInjectStylesheet = (stylesheet) => {
3
+ /**
4
+ * This hook injects the passed styles on the client side within a new <style> tag.
5
+ *
6
+ * @param css: The CSS string to be injected.
7
+ */
8
+ const useInjectStylesheet = (css) => {
5
9
  useInsertionEffect(() => {
6
- if (!stylesheet) {
10
+ if (!css) {
7
11
  return;
8
12
  }
9
13
  const styleTag = document.createElement('style');
10
14
  styleTag.setAttribute('type', 'text/css');
11
- styleTag.innerHTML = stylesheet.css;
15
+ styleTag.innerHTML = css;
12
16
  // This might cause an error with `document.head` being undefined, e.g. when the client-side
13
17
  // hydration in SSR applications failed and thus the document is not initialized.
14
18
  document.head.appendChild(styleTag);
15
- }, [stylesheet]);
19
+ return () => {
20
+ styleTag.parentNode?.removeChild(styleTag);
21
+ };
22
+ }, [css]);
16
23
  };
17
24
 
18
25
  export { useInjectStylesheet };
19
- //# sourceMappingURL=useClassName.js.map
26
+ //# sourceMappingURL=useInjectStylesheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInjectStylesheet.js","sources":["../../../src/hooks/useInjectStylesheet.ts"],"sourcesContent":["import { useInsertionEffect } from 'react';\n\n/**\n * This hook injects the passed styles on the client side within a new <style> tag.\n *\n * @param css: The CSS string to be injected.\n */\nexport const useInjectStylesheet = (css?: string) => {\n useInsertionEffect(() => {\n if (!css) {\n return;\n }\n\n const styleTag = document.createElement('style');\n styleTag.setAttribute('type', 'text/css');\n styleTag.innerHTML = css;\n\n // This might cause an error with `document.head` being undefined, e.g. when the client-side\n // hydration in SSR applications failed and thus the document is not initialized.\n document.head.appendChild(styleTag);\n\n return () => {\n styleTag.parentNode?.removeChild(styleTag);\n };\n }, [css]);\n};\n"],"names":[],"mappings":";;AAEA;;;;AAIG;AACU,MAAA,mBAAmB,GAAG,CAAC,GAAY,KAAI;IAClD,kBAAkB,CAAC,MAAK;QACtB,IAAI,CAAC,GAAG,EAAE;YACR,OAAO;SACR;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACjD,QAAA,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC1C,QAAA,QAAQ,CAAC,SAAS,GAAG,GAAG,CAAC;;;AAIzB,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAEpC,QAAA,OAAO,MAAK;AACV,YAAA,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC7C,SAAC,CAAC;AACJ,KAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACZ;;;;"}
@@ -13,7 +13,7 @@ import { useMemo } from 'react';
13
13
  * ]
14
14
  * ```
15
15
  */
16
- const createStylesheetsForBuiltInStyles = ({ designPropertiesByBreakpoint, breakpoints, node, }) => {
16
+ const createStylesheetsForBuiltInStyles = ({ designPropertiesByBreakpoint, breakpoints, node, patternNodeIdsChain, }) => {
17
17
  const flattenedDesignTokens = flattenDesignTokenRegistry(designTokensRegistry);
18
18
  const result = [];
19
19
  for (const breakpoint of breakpoints) {
@@ -45,7 +45,9 @@ const createStylesheetsForBuiltInStyles = ({ designPropertiesByBreakpoint, break
45
45
  * breakpointCss = "margin:42px;background-color:rgba(246, 246, 246, 1);"
46
46
  */
47
47
  // Create a hash ensuring stability across nodes (and breakpoints between nodes)
48
- const styleHash = md5(`${node.id}}-${breakpointCss}`);
48
+ const styleHash = patternNodeIdsChain
49
+ ? md5(`${patternNodeIdsChain}-${node.id}}-${breakpointCss}`)
50
+ : md5(`${node.id}-${breakpointCss}`);
49
51
  // Create a CSS className with internal prefix to make sure the value can be processed
50
52
  const className = `cfstyles-${styleHash}`;
51
53
  result.push({
@@ -95,15 +97,16 @@ const convertResolvedDesignValuesToMediaQuery = (stylesheetData) => {
95
97
  className: stylesheet.classNames.join(' '),
96
98
  };
97
99
  };
98
- const useMediaQuery = ({ designPropertiesByBreakpoint, breakpoints, node, }) => {
100
+ const useMediaQuery = ({ designPropertiesByBreakpoint, breakpoints, node, patternNodeIdsChain, }) => {
99
101
  return useMemo(() => {
100
102
  const stylesheetData = createStylesheetsForBuiltInStyles({
101
103
  designPropertiesByBreakpoint,
102
104
  breakpoints,
103
105
  node,
106
+ patternNodeIdsChain,
104
107
  });
105
108
  return convertResolvedDesignValuesToMediaQuery(stylesheetData);
106
- }, [designPropertiesByBreakpoint, breakpoints, node]);
109
+ }, [designPropertiesByBreakpoint, breakpoints, node, patternNodeIdsChain]);
107
110
  };
108
111
 
109
112
  export { convertResolvedDesignValuesToMediaQuery, createStylesheetsForBuiltInStyles, useMediaQuery };
@@ -1 +1 @@
1
- {"version":3,"file":"useMediaQuery.js","sources":["../../../src/hooks/useMediaQuery.ts"],"sourcesContent":["import {\n addMinHeightForEmptyStructures,\n designTokensRegistry,\n flattenDesignTokenRegistry,\n maybePopulateDesignTokenValue,\n stringifyCssProperties,\n toMediaQuery,\n buildCfStyles,\n} from '@contentful/experiences-core';\nimport { Breakpoint, ComponentTreeNode, PrimitiveValue } from '@contentful/experiences-core/types';\nimport md5 from 'md5';\nimport { useMemo } from 'react';\n\ntype ResolvedStylesheetData = Array<{\n className: string;\n breakpointCondition: string;\n css: string;\n}>;\n\n/**\n * For each provided breakpoint, create the CSS code and a unique class name.\n *\n * **Example Output:**\n * ```\n * [\n * { className: 'cfstyles-123', breakpointCondition: '*', css: 'margin:42px;' },\n * { className: 'cfstyles-456', breakpointCondition: '<768px', css: 'margin:13px;' },\n * ]\n * ```\n */\nexport const createStylesheetsForBuiltInStyles = ({\n designPropertiesByBreakpoint,\n breakpoints,\n node,\n}: {\n designPropertiesByBreakpoint: Record<string, Record<string, PrimitiveValue>>;\n breakpoints: Breakpoint[];\n node: ComponentTreeNode;\n}): ResolvedStylesheetData => {\n const flattenedDesignTokens = flattenDesignTokenRegistry(designTokensRegistry);\n\n const result: Array<{\n className: string;\n breakpointCondition: string;\n css: string;\n }> = [];\n\n for (const breakpoint of breakpoints) {\n const designProperties = designPropertiesByBreakpoint[breakpoint.id];\n if (!designProperties) {\n continue;\n }\n\n const designPropertiesWithResolvedDesignTokens = Object.entries(designProperties).reduce(\n (acc, [propertyName, value]) => ({\n ...acc,\n [propertyName]: maybePopulateDesignTokenValue(propertyName, value, flattenedDesignTokens),\n }),\n {},\n );\n /* [Data Format] `designPropertiesWithResolvedDesignTokens` is a map of property name to plain design value:\n * designPropertiesWithResolvedDesignTokens = {\n * cfMargin: '42px',\n * cfBackgroundColor: 'rgba(246, 246, 246, 1)',\n * }\n */\n\n // Convert CF-specific property names to CSS variables, e.g. `cfMargin` -> `margin`\n const cfStyles = addMinHeightForEmptyStructures(\n buildCfStyles(designPropertiesWithResolvedDesignTokens),\n node,\n );\n /* [Data Format] `cfStyles` follows the shape of CSSProperties (camelCased CSS property names):\n * cfStyles = {\n * margin: '42px',\n * backgroundColor: 'rgba(246, 246, 246, 1)',\n * }\n */\n\n // Translate the map of CSSProperties into the final shape of CSS code for this specific breakpoint\n const breakpointCss = stringifyCssProperties(cfStyles);\n /* [Data Format] `breakpointCss`:\n * breakpointCss = \"margin:42px;background-color:rgba(246, 246, 246, 1);\"\n */\n\n // Create a hash ensuring stability across nodes (and breakpoints between nodes)\n const styleHash = md5(`${node.id}}-${breakpointCss}`);\n\n // Create a CSS className with internal prefix to make sure the value can be processed\n const className = `cfstyles-${styleHash}`;\n\n result.push({\n className,\n breakpointCondition: breakpoint.query,\n css: breakpointCss,\n });\n }\n\n return result;\n};\n\n/**\n * Takes the CSS code for each breakpoint and merges them into a single CSS string.\n * It will wrap each breakpoint's CSS code in a media query (exception: default breakpoint with '*').\n *\n * **Example Input:**\n * ```\n * [\n * { className: 'cfstyles-123', breakpointCondition: '*', css: 'color:red;' },\n * { className: 'cfstyles-456', breakpointCondition: '<768px', css: 'color:blue;' },\n * ]\n * ```\n *\n * **Example Output:**\n * ```\n * '.cfstyles-123{color:red;}@media(max-width:768px){.cfstyles-456{color:blue;}}'\n * ```\n */\nexport const convertResolvedDesignValuesToMediaQuery = (stylesheetData: ResolvedStylesheetData) => {\n const stylesheet = stylesheetData.reduce(\n (acc, { breakpointCondition, className, css }) => {\n if (acc.classNames.includes(className)) {\n return acc;\n }\n\n const mediaQueryCss = toMediaQuery({\n condition: breakpointCondition,\n cssByClassName: { [className]: css },\n });\n return {\n classNames: [...acc.classNames, className],\n css: `${acc.css}${mediaQueryCss}`,\n };\n },\n {\n classNames: [] as string[],\n css: '',\n },\n );\n\n return {\n css: stylesheet.css,\n className: stylesheet.classNames.join(' '),\n };\n};\n\nexport const useMediaQuery = ({\n designPropertiesByBreakpoint,\n breakpoints,\n node,\n}: {\n designPropertiesByBreakpoint: Record<string, Record<string, any>>;\n breakpoints: Breakpoint[];\n node: ComponentTreeNode;\n}) => {\n return useMemo(() => {\n const stylesheetData = createStylesheetsForBuiltInStyles({\n designPropertiesByBreakpoint,\n breakpoints,\n node,\n });\n\n return convertResolvedDesignValuesToMediaQuery(stylesheetData);\n }, [designPropertiesByBreakpoint, breakpoints, node]);\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useMediaQuery.js","sources":["../../../src/hooks/useMediaQuery.ts"],"sourcesContent":["import {\n addMinHeightForEmptyStructures,\n designTokensRegistry,\n flattenDesignTokenRegistry,\n maybePopulateDesignTokenValue,\n stringifyCssProperties,\n toMediaQuery,\n buildCfStyles,\n} from '@contentful/experiences-core';\nimport { Breakpoint, ComponentTreeNode, PrimitiveValue } from '@contentful/experiences-core/types';\nimport md5 from 'md5';\nimport { useMemo } from 'react';\n\ntype ResolvedStylesheetData = Array<{\n className: string;\n breakpointCondition: string;\n css: string;\n}>;\n\n/**\n * For each provided breakpoint, create the CSS code and a unique class name.\n *\n * **Example Output:**\n * ```\n * [\n * { className: 'cfstyles-123', breakpointCondition: '*', css: 'margin:42px;' },\n * { className: 'cfstyles-456', breakpointCondition: '<768px', css: 'margin:13px;' },\n * ]\n * ```\n */\nexport const createStylesheetsForBuiltInStyles = ({\n designPropertiesByBreakpoint,\n breakpoints,\n node,\n patternNodeIdsChain,\n}: {\n designPropertiesByBreakpoint: Record<string, Record<string, PrimitiveValue>>;\n breakpoints: Breakpoint[];\n node: ComponentTreeNode;\n patternNodeIdsChain?: string;\n}): ResolvedStylesheetData => {\n const flattenedDesignTokens = flattenDesignTokenRegistry(designTokensRegistry);\n\n const result: Array<{\n className: string;\n breakpointCondition: string;\n css: string;\n }> = [];\n\n for (const breakpoint of breakpoints) {\n const designProperties = designPropertiesByBreakpoint[breakpoint.id];\n if (!designProperties) {\n continue;\n }\n\n const designPropertiesWithResolvedDesignTokens = Object.entries(designProperties).reduce(\n (acc, [propertyName, value]) => ({\n ...acc,\n [propertyName]: maybePopulateDesignTokenValue(propertyName, value, flattenedDesignTokens),\n }),\n {},\n );\n /* [Data Format] `designPropertiesWithResolvedDesignTokens` is a map of property name to plain design value:\n * designPropertiesWithResolvedDesignTokens = {\n * cfMargin: '42px',\n * cfBackgroundColor: 'rgba(246, 246, 246, 1)',\n * }\n */\n\n // Convert CF-specific property names to CSS variables, e.g. `cfMargin` -> `margin`\n const cfStyles = addMinHeightForEmptyStructures(\n buildCfStyles(designPropertiesWithResolvedDesignTokens),\n node,\n );\n /* [Data Format] `cfStyles` follows the shape of CSSProperties (camelCased CSS property names):\n * cfStyles = {\n * margin: '42px',\n * backgroundColor: 'rgba(246, 246, 246, 1)',\n * }\n */\n\n // Translate the map of CSSProperties into the final shape of CSS code for this specific breakpoint\n const breakpointCss = stringifyCssProperties(cfStyles);\n /* [Data Format] `breakpointCss`:\n * breakpointCss = \"margin:42px;background-color:rgba(246, 246, 246, 1);\"\n */\n\n // Create a hash ensuring stability across nodes (and breakpoints between nodes)\n const styleHash = patternNodeIdsChain\n ? md5(`${patternNodeIdsChain}-${node.id}}-${breakpointCss}`)\n : md5(`${node.id}-${breakpointCss}`);\n\n // Create a CSS className with internal prefix to make sure the value can be processed\n const className = `cfstyles-${styleHash}`;\n\n result.push({\n className,\n breakpointCondition: breakpoint.query,\n css: breakpointCss,\n });\n }\n\n return result;\n};\n\n/**\n * Takes the CSS code for each breakpoint and merges them into a single CSS string.\n * It will wrap each breakpoint's CSS code in a media query (exception: default breakpoint with '*').\n *\n * **Example Input:**\n * ```\n * [\n * { className: 'cfstyles-123', breakpointCondition: '*', css: 'color:red;' },\n * { className: 'cfstyles-456', breakpointCondition: '<768px', css: 'color:blue;' },\n * ]\n * ```\n *\n * **Example Output:**\n * ```\n * '.cfstyles-123{color:red;}@media(max-width:768px){.cfstyles-456{color:blue;}}'\n * ```\n */\nexport const convertResolvedDesignValuesToMediaQuery = (stylesheetData: ResolvedStylesheetData) => {\n const stylesheet = stylesheetData.reduce(\n (acc, { breakpointCondition, className, css }) => {\n if (acc.classNames.includes(className)) {\n return acc;\n }\n\n const mediaQueryCss = toMediaQuery({\n condition: breakpointCondition,\n cssByClassName: { [className]: css },\n });\n return {\n classNames: [...acc.classNames, className],\n css: `${acc.css}${mediaQueryCss}`,\n };\n },\n {\n classNames: [] as string[],\n css: '',\n },\n );\n\n return {\n css: stylesheet.css,\n className: stylesheet.classNames.join(' '),\n };\n};\n\nexport const useMediaQuery = ({\n designPropertiesByBreakpoint,\n breakpoints,\n node,\n patternNodeIdsChain,\n}: {\n designPropertiesByBreakpoint: Record<string, Record<string, any>>;\n breakpoints: Breakpoint[];\n node: ComponentTreeNode;\n patternNodeIdsChain?: string;\n}) => {\n return useMemo(() => {\n const stylesheetData = createStylesheetsForBuiltInStyles({\n designPropertiesByBreakpoint,\n breakpoints,\n node,\n patternNodeIdsChain,\n });\n\n return convertResolvedDesignValuesToMediaQuery(stylesheetData);\n }, [designPropertiesByBreakpoint, breakpoints, node, patternNodeIdsChain]);\n};\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ import * as _contentful_experiences_core_constants from '@contentful/experiences
8
8
  export { CF_STYLE_ATTRIBUTES, CONTENTFUL_COMPONENTS, LATEST_SCHEMA_VERSION } from '@contentful/experiences-core/constants';
9
9
  import { ContentfulClientApi } from 'contentful';
10
10
 
11
- declare const SDK_VERSION = "1.37.1";
11
+ declare const SDK_VERSION = "1.37.2-dev-20250515T1505-4c9ed48.0";
12
12
 
13
13
  type ExperienceRootProps = {
14
14
  experience?: Experience<EntityStore> | string | null;
@@ -1,4 +1,4 @@
1
- const SDK_VERSION = '1.37.1';
1
+ const SDK_VERSION = '1.37.2-dev-20250515T1505-4c9ed48.0';
2
2
 
3
3
  export { SDK_VERSION };
4
4
  //# sourceMappingURL=sdkVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sdkVersion.js","sources":["../../src/sdkVersion.ts"],"sourcesContent":["export const SDK_VERSION = '1.37.1';\n"],"names":[],"mappings":"AAAO,MAAM,WAAW,GAAG;;;;"}
1
+ {"version":3,"file":"sdkVersion.js","sources":["../../src/sdkVersion.ts"],"sourcesContent":["export const SDK_VERSION = '1.37.2-dev-20250515T1505-4c9ed48.0';\n"],"names":[],"mappings":"AAAO,MAAM,WAAW,GAAG;;;;"}
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
2
  import type { Breakpoint, ComponentTreeNode, PrimitiveValue } from '@contentful/experiences-core/types';
3
- interface PreviewUnboundImageProps {
3
+ type PreviewUnboundImageProps = {
4
4
  breakpoints: Breakpoint[];
5
5
  node: ComponentTreeNode;
6
6
  nodeProps: Record<PropertyKey, PrimitiveValue>;
7
7
  component: React.ElementType;
8
- }
8
+ patternNodeIdsChain: string;
9
+ };
9
10
  /**
10
11
  * This component is used to render a placeholder Image component in the preview
11
12
  * when the image is unbound. It applies the Image size styles to a wrapping div.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * This hook injects the passed styles on the client side within a new <style> tag.
3
+ *
4
+ * @param css: The CSS string to be injected.
5
+ */
6
+ export declare const useInjectStylesheet: (css?: string) => void;
@@ -15,10 +15,11 @@ type ResolvedStylesheetData = Array<{
15
15
  * ]
16
16
  * ```
17
17
  */
18
- export declare const createStylesheetsForBuiltInStyles: ({ designPropertiesByBreakpoint, breakpoints, node, }: {
18
+ export declare const createStylesheetsForBuiltInStyles: ({ designPropertiesByBreakpoint, breakpoints, node, patternNodeIdsChain, }: {
19
19
  designPropertiesByBreakpoint: Record<string, Record<string, PrimitiveValue>>;
20
20
  breakpoints: Breakpoint[];
21
21
  node: ComponentTreeNode;
22
+ patternNodeIdsChain?: string;
22
23
  }) => ResolvedStylesheetData;
23
24
  /**
24
25
  * Takes the CSS code for each breakpoint and merges them into a single CSS string.
@@ -41,10 +42,11 @@ export declare const convertResolvedDesignValuesToMediaQuery: (stylesheetData: R
41
42
  css: string;
42
43
  className: string;
43
44
  };
44
- export declare const useMediaQuery: ({ designPropertiesByBreakpoint, breakpoints, node, }: {
45
+ export declare const useMediaQuery: ({ designPropertiesByBreakpoint, breakpoints, node, patternNodeIdsChain, }: {
45
46
  designPropertiesByBreakpoint: Record<string, Record<string, any>>;
46
47
  breakpoints: Breakpoint[];
47
48
  node: ComponentTreeNode;
49
+ patternNodeIdsChain?: string;
48
50
  }) => {
49
51
  css: string;
50
52
  className: string;
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "1.37.1";
1
+ export declare const SDK_VERSION = "1.37.2-dev-20250515T1505-4c9ed48.0";
@@ -10,11 +10,12 @@ import { BoundComponentPropertyTypes, BoundValue, Breakpoint, ComponentDefinitio
10
10
  * 4) Those DesignValue props which can NOT be converted to CSS (custom design props) should be resolved dynamically
11
11
  * for each breakpoint
12
12
  */
13
- export declare const parseComponentProps: ({ breakpoints, mainBreakpoint, componentDefinition, node, resolveCustomDesignValue, resolveBoundValue, resolveHyperlinkValue, resolveUnboundValue, }: {
13
+ export declare const parseComponentProps: ({ breakpoints, mainBreakpoint, componentDefinition, patternNodeIdsChain, node, resolveCustomDesignValue, resolveBoundValue, resolveHyperlinkValue, resolveUnboundValue, }: {
14
14
  breakpoints: Breakpoint[];
15
15
  mainBreakpoint: Breakpoint;
16
- node: ComponentTreeNode;
17
16
  componentDefinition: ComponentDefinition;
17
+ patternNodeIdsChain?: string;
18
+ node: ComponentTreeNode;
18
19
  resolveCustomDesignValue: (data: {
19
20
  propertyName: string;
20
21
  valuesByBreakpoint: Record<string, PrimitiveValue>;
@@ -16,7 +16,7 @@ const isSpecialCaseCssProp = (propName) => {
16
16
  * 4) Those DesignValue props which can NOT be converted to CSS (custom design props) should be resolved dynamically
17
17
  * for each breakpoint
18
18
  */
19
- const parseComponentProps = ({ breakpoints, mainBreakpoint, componentDefinition, node, resolveCustomDesignValue, resolveBoundValue, resolveHyperlinkValue, resolveUnboundValue, }) => {
19
+ const parseComponentProps = ({ breakpoints, mainBreakpoint, componentDefinition, patternNodeIdsChain, node, resolveCustomDesignValue, resolveBoundValue, resolveHyperlinkValue, resolveUnboundValue, }) => {
20
20
  const styleProps = {};
21
21
  const customDesignProps = {};
22
22
  const contentProps = {};
@@ -117,6 +117,7 @@ const parseComponentProps = ({ breakpoints, mainBreakpoint, componentDefinition,
117
117
  designPropertiesByBreakpoint: stylePropsIndexedByBreakpoint,
118
118
  breakpoints,
119
119
  node,
120
+ patternNodeIdsChain,
120
121
  });
121
122
  /* [Data Format] Stylesheet data provides objects containing `className`, `breakpointCondition`, and `css`.
122
123
  * stylesheetData = [{
@@ -1 +1 @@
1
- {"version":3,"file":"parseComponentProps.js","sources":["../../../src/utils/parseComponentProps.ts"],"sourcesContent":["import { isCfStyleAttribute, debug } from '@contentful/experiences-core';\nimport {\n BoundComponentPropertyTypes,\n BoundValue,\n Breakpoint,\n ComponentDefinition,\n ComponentDefinitionVariable,\n ComponentDefinitionVariableType,\n ComponentTreeNode,\n DesignValue,\n PrimitiveValue,\n} from '@contentful/experiences-core/types';\nimport { convertResolvedDesignValuesToMediaQuery } from '../hooks/useMediaQuery';\nimport { createStylesheetsForBuiltInStyles } from '../hooks/useMediaQuery';\n\n// TODO: Test this for nested patterns as the name might be just a random hash without the actual name (needs to be validated).\nconst isSpecialCaseCssProp = (propName: string) => {\n return propName === 'cfBackgroundImageUrl' || propName.startsWith('cfBackgroundImageUrl_');\n};\n\n/**\n * The previous logic of prop mapping was too complex and mixed different ues cases together.\n * In this function, I aim to simplify the logic by focusing on the following specific cases FOR PREVIEW/DELIVERY MODES\n * 1) Any non `DesignValue` props should be resolved and returned as is\n * 2) Some exceptions like `cfImageAsset` and `cfBackgroundImageUrl` (BoundValue) should be handled separately\n * and be resolved for the default breakpoint only (cause we don't allow binding per breakpoint anyway)\n * 3) Those DesignValue props which can be converted to CSS should be grouped and resolved into a CSS media query\n * for each breakpoint\n * 4) Those DesignValue props which can NOT be converted to CSS (custom design props) should be resolved dynamically\n * for each breakpoint\n */\nexport const parseComponentProps = ({\n breakpoints,\n mainBreakpoint,\n componentDefinition,\n node,\n resolveCustomDesignValue,\n resolveBoundValue,\n resolveHyperlinkValue,\n resolveUnboundValue,\n}: {\n breakpoints: Breakpoint[];\n mainBreakpoint: Breakpoint;\n node: ComponentTreeNode;\n componentDefinition: ComponentDefinition;\n resolveCustomDesignValue: (data: {\n propertyName: string;\n valuesByBreakpoint: Record<string, PrimitiveValue>;\n }) => PrimitiveValue;\n resolveBoundValue: (data: {\n propertyName: string;\n dataType: ComponentDefinitionVariableType;\n binding: BoundValue;\n }) => BoundComponentPropertyTypes;\n resolveHyperlinkValue: (data: { linkTargetKey: string }) => string | null;\n resolveUnboundValue: (data: {\n mappingKey: string;\n defaultValue: ComponentDefinitionVariable['defaultValue'];\n }) => PrimitiveValue;\n}) => {\n const styleProps: Record<string, DesignValue['valuesByBreakpoint']> = {};\n const customDesignProps: Record<string, PrimitiveValue> = {};\n const contentProps: Record<string, PrimitiveValue> = {};\n\n debug.log('Parsing component props for node with id: ', node.id);\n\n for (const [propName, propDefinition] of Object.entries(componentDefinition.variables)) {\n const propertyValue = node.variables[propName];\n if (!propertyValue) continue;\n\n switch (propertyValue.type) {\n case 'DesignValue': {\n if (isCfStyleAttribute(propName)) {\n // for such properties we know how to convert them to CSS, so we will build a media query from it below after the loop is over\n styleProps[propName] = propertyValue.valuesByBreakpoint;\n } else {\n // for custom design props, the value will be resolved with the javascript per breakpoint at runtime\n customDesignProps[propName] = resolveCustomDesignValue({\n propertyName: propName,\n valuesByBreakpoint: propertyValue.valuesByBreakpoint,\n });\n }\n break;\n }\n case 'BoundValue': {\n const boundValue = resolveBoundValue({\n propertyName: propName,\n dataType: propDefinition.type as ComponentDefinitionVariableType,\n binding: propertyValue,\n });\n\n const propValue = boundValue ?? propDefinition.defaultValue;\n\n if (isSpecialCaseCssProp(propName)) {\n styleProps[propName] = { [mainBreakpoint.id]: propValue };\n } else {\n contentProps[propName] = propValue;\n }\n break;\n }\n\n case 'HyperlinkValue': {\n const hyperlink = resolveHyperlinkValue({\n linkTargetKey: propertyValue.linkTargetKey,\n });\n if (hyperlink) {\n contentProps[propName] = hyperlink;\n }\n break;\n }\n case 'UnboundValue': {\n const unboundValue = resolveUnboundValue({\n mappingKey: propertyValue.key,\n defaultValue: propDefinition.defaultValue,\n });\n\n if (isSpecialCaseCssProp(propName)) {\n styleProps[propName] = { [mainBreakpoint.id]: unboundValue };\n } else {\n contentProps[propName] = unboundValue;\n }\n break;\n }\n case 'ComponentValue':\n // We're rendering a pattern entry. Content cannot be set for ComponentValue type properties\n // directly in the pattern so we can safely use the default value\n // This can either be a design (style) or a content variable\n contentProps[propName] = propDefinition.defaultValue;\n break;\n default:\n break;\n }\n }\n /* [Data Format] After resolving all properties, `styleProps` contains solely the plain design values\n * styleProps = {\n * cfMargin: { desktop: '42px', tablet: '13px' },\n * cfBackgroundColor: { desktop: 'rgba(246, 246, 246, 1)' },\n * cfBackgroundImage: { desktop: 'url(https://example.com/image.jpg)' }\n * }\n */\n\n const stylePropsIndexedByBreakpoint = Object.entries(styleProps).reduce<\n Record<string, Record<string, PrimitiveValue>>\n >((acc, [propName, valuesByBreakpoint]) => {\n for (const [breakpointId, value] of Object.entries(valuesByBreakpoint)) {\n if (!acc[breakpointId]) {\n acc[breakpointId] = {};\n }\n\n acc[breakpointId][propName] = value;\n }\n\n return acc;\n }, {});\n /* [Data Format] `stylePropsIndexedByBreakpoint` contains the plain design values grouped by breakpoint\n * stylePropsIndexedByBreakpoint = {\n * desktop: {\n * cfMargin: '42px',\n * cfBackgroundColor: 'rgba(246, 246, 246, 1)',\n * cfBackgroundImage: 'url(https://example.com/image.jpg)'\n * },\n * tablet: {\n * cfMargin: '13px'\n * }\n * }\n */\n\n const stylesheetData = createStylesheetsForBuiltInStyles({\n designPropertiesByBreakpoint: stylePropsIndexedByBreakpoint,\n breakpoints,\n node,\n });\n /* [Data Format] Stylesheet data provides objects containing `className`, `breakpointCondition`, and `css`.\n * stylesheetData = [{\n * className: 'uniqueMD5Hash',\n * breakpointCondition: '<768px',\n * css: 'margin:13px;'\n * }, ...]\n */\n const mediaQuery = convertResolvedDesignValuesToMediaQuery(stylesheetData);\n /* [Data Format] `mediaQuery` is a joined string of all media query CSS code\n * mediaQuery = \".cfstyles-123{margin:42px;}@media(max-width:768px){.cfstyles-456{margin:13px;}}\"\n */\n return {\n styleProps,\n mediaQuery,\n customDesignProps,\n contentProps,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parseComponentProps.js","sources":["../../../src/utils/parseComponentProps.ts"],"sourcesContent":["import { isCfStyleAttribute, debug } from '@contentful/experiences-core';\nimport {\n BoundComponentPropertyTypes,\n BoundValue,\n Breakpoint,\n ComponentDefinition,\n ComponentDefinitionVariable,\n ComponentDefinitionVariableType,\n ComponentTreeNode,\n DesignValue,\n PrimitiveValue,\n} from '@contentful/experiences-core/types';\nimport { convertResolvedDesignValuesToMediaQuery } from '../hooks/useMediaQuery';\nimport { createStylesheetsForBuiltInStyles } from '../hooks/useMediaQuery';\n\n// TODO: Test this for nested patterns as the name might be just a random hash without the actual name (needs to be validated).\nconst isSpecialCaseCssProp = (propName: string) => {\n return propName === 'cfBackgroundImageUrl' || propName.startsWith('cfBackgroundImageUrl_');\n};\n\n/**\n * The previous logic of prop mapping was too complex and mixed different ues cases together.\n * In this function, I aim to simplify the logic by focusing on the following specific cases FOR PREVIEW/DELIVERY MODES\n * 1) Any non `DesignValue` props should be resolved and returned as is\n * 2) Some exceptions like `cfImageAsset` and `cfBackgroundImageUrl` (BoundValue) should be handled separately\n * and be resolved for the default breakpoint only (cause we don't allow binding per breakpoint anyway)\n * 3) Those DesignValue props which can be converted to CSS should be grouped and resolved into a CSS media query\n * for each breakpoint\n * 4) Those DesignValue props which can NOT be converted to CSS (custom design props) should be resolved dynamically\n * for each breakpoint\n */\nexport const parseComponentProps = ({\n breakpoints,\n mainBreakpoint,\n componentDefinition,\n patternNodeIdsChain,\n node,\n resolveCustomDesignValue,\n resolveBoundValue,\n resolveHyperlinkValue,\n resolveUnboundValue,\n}: {\n breakpoints: Breakpoint[];\n mainBreakpoint: Breakpoint;\n componentDefinition: ComponentDefinition;\n patternNodeIdsChain?: string;\n node: ComponentTreeNode;\n resolveCustomDesignValue: (data: {\n propertyName: string;\n valuesByBreakpoint: Record<string, PrimitiveValue>;\n }) => PrimitiveValue;\n resolveBoundValue: (data: {\n propertyName: string;\n dataType: ComponentDefinitionVariableType;\n binding: BoundValue;\n }) => BoundComponentPropertyTypes;\n resolveHyperlinkValue: (data: { linkTargetKey: string }) => string | null;\n resolveUnboundValue: (data: {\n mappingKey: string;\n defaultValue: ComponentDefinitionVariable['defaultValue'];\n }) => PrimitiveValue;\n}) => {\n const styleProps: Record<string, DesignValue['valuesByBreakpoint']> = {};\n const customDesignProps: Record<string, PrimitiveValue> = {};\n const contentProps: Record<string, PrimitiveValue> = {};\n\n debug.log('Parsing component props for node with id: ', node.id);\n\n for (const [propName, propDefinition] of Object.entries(componentDefinition.variables)) {\n const propertyValue = node.variables[propName];\n if (!propertyValue) continue;\n\n switch (propertyValue.type) {\n case 'DesignValue': {\n if (isCfStyleAttribute(propName)) {\n // for such properties we know how to convert them to CSS, so we will build a media query from it below after the loop is over\n styleProps[propName] = propertyValue.valuesByBreakpoint;\n } else {\n // for custom design props, the value will be resolved with the javascript per breakpoint at runtime\n customDesignProps[propName] = resolveCustomDesignValue({\n propertyName: propName,\n valuesByBreakpoint: propertyValue.valuesByBreakpoint,\n });\n }\n break;\n }\n case 'BoundValue': {\n const boundValue = resolveBoundValue({\n propertyName: propName,\n dataType: propDefinition.type as ComponentDefinitionVariableType,\n binding: propertyValue,\n });\n\n const propValue = boundValue ?? propDefinition.defaultValue;\n\n if (isSpecialCaseCssProp(propName)) {\n styleProps[propName] = { [mainBreakpoint.id]: propValue };\n } else {\n contentProps[propName] = propValue;\n }\n break;\n }\n\n case 'HyperlinkValue': {\n const hyperlink = resolveHyperlinkValue({\n linkTargetKey: propertyValue.linkTargetKey,\n });\n if (hyperlink) {\n contentProps[propName] = hyperlink;\n }\n break;\n }\n case 'UnboundValue': {\n const unboundValue = resolveUnboundValue({\n mappingKey: propertyValue.key,\n defaultValue: propDefinition.defaultValue,\n });\n\n if (isSpecialCaseCssProp(propName)) {\n styleProps[propName] = { [mainBreakpoint.id]: unboundValue };\n } else {\n contentProps[propName] = unboundValue;\n }\n break;\n }\n case 'ComponentValue':\n // We're rendering a pattern entry. Content cannot be set for ComponentValue type properties\n // directly in the pattern so we can safely use the default value\n // This can either be a design (style) or a content variable\n contentProps[propName] = propDefinition.defaultValue;\n break;\n default:\n break;\n }\n }\n /* [Data Format] After resolving all properties, `styleProps` contains solely the plain design values\n * styleProps = {\n * cfMargin: { desktop: '42px', tablet: '13px' },\n * cfBackgroundColor: { desktop: 'rgba(246, 246, 246, 1)' },\n * cfBackgroundImage: { desktop: 'url(https://example.com/image.jpg)' }\n * }\n */\n\n const stylePropsIndexedByBreakpoint = Object.entries(styleProps).reduce<\n Record<string, Record<string, PrimitiveValue>>\n >((acc, [propName, valuesByBreakpoint]) => {\n for (const [breakpointId, value] of Object.entries(valuesByBreakpoint)) {\n if (!acc[breakpointId]) {\n acc[breakpointId] = {};\n }\n\n acc[breakpointId][propName] = value;\n }\n\n return acc;\n }, {});\n /* [Data Format] `stylePropsIndexedByBreakpoint` contains the plain design values grouped by breakpoint\n * stylePropsIndexedByBreakpoint = {\n * desktop: {\n * cfMargin: '42px',\n * cfBackgroundColor: 'rgba(246, 246, 246, 1)',\n * cfBackgroundImage: 'url(https://example.com/image.jpg)'\n * },\n * tablet: {\n * cfMargin: '13px'\n * }\n * }\n */\n\n const stylesheetData = createStylesheetsForBuiltInStyles({\n designPropertiesByBreakpoint: stylePropsIndexedByBreakpoint,\n breakpoints,\n node,\n patternNodeIdsChain,\n });\n /* [Data Format] Stylesheet data provides objects containing `className`, `breakpointCondition`, and `css`.\n * stylesheetData = [{\n * className: 'uniqueMD5Hash',\n * breakpointCondition: '<768px',\n * css: 'margin:13px;'\n * }, ...]\n */\n const mediaQuery = convertResolvedDesignValuesToMediaQuery(stylesheetData);\n /* [Data Format] `mediaQuery` is a joined string of all media query CSS code\n * mediaQuery = \".cfstyles-123{margin:42px;}@media(max-width:768px){.cfstyles-456{margin:13px;}}\"\n */\n return {\n styleProps,\n mediaQuery,\n customDesignProps,\n contentProps,\n };\n};\n"],"names":[],"mappings":";;;AAeA;AACA,MAAM,oBAAoB,GAAG,CAAC,QAAgB,KAAI;IAChD,OAAO,QAAQ,KAAK,sBAAsB,IAAI,QAAQ,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;AAC7F,CAAC,CAAC;AAEF;;;;;;;;;;AAUG;AACU,MAAA,mBAAmB,GAAG,CAAC,EAClC,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,IAAI,EACJ,wBAAwB,EACxB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GAqBpB,KAAI;IACH,MAAM,UAAU,GAAsD,EAAE,CAAC;IACzE,MAAM,iBAAiB,GAAmC,EAAE,CAAC;IAC7D,MAAM,YAAY,GAAmC,EAAE,CAAC;IAExD,KAAK,CAAC,GAAG,CAAC,4CAA4C,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;AAEjE,IAAA,KAAK,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE;QACtF,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC/C,QAAA,IAAI,CAAC,aAAa;YAAE,SAAS;AAE7B,QAAA,QAAQ,aAAa,CAAC,IAAI;YACxB,KAAK,aAAa,EAAE;AAClB,gBAAA,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE;;AAEhC,oBAAA,UAAU,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,kBAAkB,CAAC;iBACzD;qBAAM;;AAEL,oBAAA,iBAAiB,CAAC,QAAQ,CAAC,GAAG,wBAAwB,CAAC;AACrD,wBAAA,YAAY,EAAE,QAAQ;wBACtB,kBAAkB,EAAE,aAAa,CAAC,kBAAkB;AACrD,qBAAA,CAAC,CAAC;iBACJ;gBACD,MAAM;aACP;YACD,KAAK,YAAY,EAAE;gBACjB,MAAM,UAAU,GAAG,iBAAiB,CAAC;AACnC,oBAAA,YAAY,EAAE,QAAQ;oBACtB,QAAQ,EAAE,cAAc,CAAC,IAAuC;AAChE,oBAAA,OAAO,EAAE,aAAa;AACvB,iBAAA,CAAC,CAAC;AAEH,gBAAA,MAAM,SAAS,GAAG,UAAU,IAAI,cAAc,CAAC,YAAY,CAAC;AAE5D,gBAAA,IAAI,oBAAoB,CAAC,QAAQ,CAAC,EAAE;AAClC,oBAAA,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC;iBAC3D;qBAAM;AACL,oBAAA,YAAY,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;iBACpC;gBACD,MAAM;aACP;YAED,KAAK,gBAAgB,EAAE;gBACrB,MAAM,SAAS,GAAG,qBAAqB,CAAC;oBACtC,aAAa,EAAE,aAAa,CAAC,aAAa;AAC3C,iBAAA,CAAC,CAAC;gBACH,IAAI,SAAS,EAAE;AACb,oBAAA,YAAY,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;iBACpC;gBACD,MAAM;aACP;YACD,KAAK,cAAc,EAAE;gBACnB,MAAM,YAAY,GAAG,mBAAmB,CAAC;oBACvC,UAAU,EAAE,aAAa,CAAC,GAAG;oBAC7B,YAAY,EAAE,cAAc,CAAC,YAAY;AAC1C,iBAAA,CAAC,CAAC;AAEH,gBAAA,IAAI,oBAAoB,CAAC,QAAQ,CAAC,EAAE;AAClC,oBAAA,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,GAAG,YAAY,EAAE,CAAC;iBAC9D;qBAAM;AACL,oBAAA,YAAY,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC;iBACvC;gBACD,MAAM;aACP;AACD,YAAA,KAAK,gBAAgB;;;;AAInB,gBAAA,YAAY,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,YAAY,CAAC;gBACrD,MAAM;SAGT;KACF;AACD;;;;;;AAMG;IAEH,MAAM,6BAA6B,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAErE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,kBAAkB,CAAC,KAAI;AACxC,QAAA,KAAK,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACtE,YAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;AACtB,gBAAA,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;aACxB;YAED,GAAG,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;SACrC;AAED,QAAA,OAAO,GAAG,CAAC;KACZ,EAAE,EAAE,CAAC,CAAC;AACP;;;;;;;;;;;AAWG;IAEH,MAAM,cAAc,GAAG,iCAAiC,CAAC;AACvD,QAAA,4BAA4B,EAAE,6BAA6B;QAC3D,WAAW;QACX,IAAI;QACJ,mBAAmB;AACpB,KAAA,CAAC,CAAC;AACH;;;;;;AAMG;AACH,IAAA,MAAM,UAAU,GAAG,uCAAuC,CAAC,cAAc,CAAC,CAAC;AAC3E;;AAEG;IACH,OAAO;QACL,UAAU;QACV,UAAU;QACV,iBAAiB;QACjB,YAAY;KACb,CAAC;AACJ;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experiences-sdk-react",
3
- "version": "1.37.1",
3
+ "version": "1.37.2-dev-20250515T1505-4c9ed48.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "typings": "./dist/src/index.d.ts",
@@ -41,10 +41,10 @@
41
41
  "depcruise": "depcruise src"
42
42
  },
43
43
  "dependencies": {
44
- "@contentful/experiences-components-react": "1.37.1",
45
- "@contentful/experiences-core": "1.37.1",
46
- "@contentful/experiences-validators": "1.37.1",
47
- "@contentful/experiences-visual-editor-react": "1.37.1",
44
+ "@contentful/experiences-components-react": "1.37.2-dev-20250515T1505-4c9ed48.0",
45
+ "@contentful/experiences-core": "1.37.2-dev-20250515T1505-4c9ed48.0",
46
+ "@contentful/experiences-validators": "1.37.2-dev-20250515T1505-4c9ed48.0",
47
+ "@contentful/experiences-visual-editor-react": "1.37.2-dev-20250515T1505-4c9ed48.0",
48
48
  "@contentful/rich-text-types": "^17.0.0",
49
49
  "classnames": "^2.3.2",
50
50
  "csstype": "^3.1.2",
@@ -102,5 +102,5 @@
102
102
  "dist",
103
103
  "package.json"
104
104
  ],
105
- "gitHead": "d2aa7b748fdff795f1e9b33fd0b3d06dd3b62cb7"
105
+ "gitHead": "f84d3f9e05c9e929dffd8c93c411b51f056498c7"
106
106
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"useClassName.js","sources":["../../../src/hooks/useClassName.ts"],"sourcesContent":["import { useLayoutEffect, useState, useInsertionEffect } from 'react';\n\nimport {\n buildCfStyles,\n addMinHeightForEmptyStructures,\n buildStyleTag,\n} from '@contentful/experiences-core';\nimport { ComponentTreeNode } from '@contentful/experiences-core/types';\n\n/**\n * This hook can generate className and inject styles on a client side as a <style> tag\n * or it derives the className set on the server side\n *\n * @param node: the componenet node for which the styles will be injected\n * @param props: the props of the component, represented by the node\n * @returns the className that was eitner generated on the client side or derived from the value, set on server side\n */\nexport const useClassName = ({\n node,\n props,\n}: {\n node: ComponentTreeNode;\n props: Record<string, any>;\n}) => {\n const [className, setClassName] = useState<string>(props.cfSsrClassName ?? '');\n // Once our React support allows it (>=18), this should be implemented with useInsertionEffect.\n useLayoutEffect(() => {\n if (props.cfSsrClassName) {\n // class name has been already set on the server side. No need to calculate it on client side anymore\n return;\n }\n\n const cfStyles = addMinHeightForEmptyStructures(buildCfStyles(props), node);\n\n if (Object.keys(cfStyles).length === 0) {\n return;\n }\n\n const [className, styleRule] = buildStyleTag({ styles: cfStyles });\n\n if (!className || !styleRule) {\n return;\n }\n\n const styleTag = document.createElement('style');\n styleTag.dataset['cfStyles'] = className;\n\n setClassName(className);\n\n document.head.appendChild(styleTag).innerHTML = styleRule;\n }, [props, node]);\n\n return className;\n};\n\nexport const useInjectStylesheet = (stylesheet?: { css: string; className: string }) => {\n useInsertionEffect(() => {\n if (!stylesheet) {\n return;\n }\n\n const styleTag = document.createElement('style');\n styleTag.setAttribute('type', 'text/css');\n styleTag.innerHTML = stylesheet.css;\n\n // This might cause an error with `document.head` being undefined, e.g. when the client-side\n // hydration in SSR applications failed and thus the document is not initialized.\n document.head.appendChild(styleTag);\n }, [stylesheet]);\n};\n"],"names":[],"mappings":";;;AAuDa,MAAA,mBAAmB,GAAG,CAAC,UAA+C,KAAI;IACrF,kBAAkB,CAAC,MAAK;QACtB,IAAI,CAAC,UAAU,EAAE;YACf,OAAO;SACR;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACjD,QAAA,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC1C,QAAA,QAAQ,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC;;;AAIpC,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACtC,KAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACnB;;;;"}
@@ -1,17 +0,0 @@
1
- import { ComponentTreeNode } from '@contentful/experiences-core/types';
2
- /**
3
- * This hook can generate className and inject styles on a client side as a <style> tag
4
- * or it derives the className set on the server side
5
- *
6
- * @param node: the componenet node for which the styles will be injected
7
- * @param props: the props of the component, represented by the node
8
- * @returns the className that was eitner generated on the client side or derived from the value, set on server side
9
- */
10
- export declare const useClassName: ({ node, props, }: {
11
- node: ComponentTreeNode;
12
- props: Record<string, any>;
13
- }) => string;
14
- export declare const useInjectStylesheet: (stylesheet?: {
15
- css: string;
16
- className: string;
17
- }) => void;