import { getLayoutStyles, StructuredBlockAny, StructuredBlockType } from '@cntrl-site/sdk'; import { ComponentType, FC, useId } from 'react'; import JSXStyle from 'styled-jsx/style'; import { useCntrlContext } from '../../provider/useCntrlContext'; import { parseSizing } from '../items/useSizing'; import { StructuredComponent } from './StructuredComponent/StructuredComponent'; export interface StructuredBlockItemProps { block: I; } interface Props { block: StructuredBlockAny; maxWidthMap: Record; } const noop = () => null; const itemsMap: Record>> = { [StructuredBlockType.Component]: StructuredComponent, [StructuredBlockType.RichText]: noop, [StructuredBlockType.Image]: noop, [StructuredBlockType.VimeoEmbed]: noop, [StructuredBlockType.YoutubeEmbed]: noop, }; export const StructuredBlockItem: FC = ({ block, maxWidthMap }) => { const reactId = useId(); const id = `${reactId}-item-${block.id}`; const { layouts } = useCntrlContext(); const layoutValues: Record[] = [block.area, block.layoutParams, block.hidden ?? {}, maxWidthMap]; const ItemComponent = itemsMap[block.type] || noop; return (
{` ${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hidden, maxWidth]) => { const sizingAxis = parseSizing(layoutParams.sizing); return (` .structured-block-item-${block.id} { display: ${hidden ? 'none' : 'block'}; align-self: ${getAlignSelf(area.alignment ?? 'center')}; width: ${sizingAxis.x === 'manual' && area.width ? `${area.width * 100}vw` : maxWidth ?? 'max-content'}; height: ${sizingAxis.y === 'manual' && area.height ? `${area.height * 100}vw` : 'unset'}; padding-top: ${area.paddingTop ? `${area.paddingTop * 100}vw` : 'unset'}; outline: none; left: ${(area.horizontalOffset ?? 0) * 100}vw; position: relative; z-index: ${area.zIndex}; } `); })} `}
); }; function getAlignSelf(alignment: 'left' | 'center' | 'right') { switch (alignment) { case 'left': return 'start'; case 'right': return 'end'; default: return 'center'; } }