From 4acbeefaedb8b32cacd0583b691e936ac77b5744 Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Sun, 26 Apr 2026 20:24:28 -0700 Subject: [PATCH] fix(container): align block children when Content Alignment is set textAlign only affects inline content, so block children like ImageBlock (display:block, width:100%) ignored it. Switch to flex-column with align-items mapped from textAlign whenever alignment is set; layout is unchanged when alignment is unset. Co-Authored-By: Claude Opus 4.7 (1M context) --- craft/src/components/layout/Container.tsx | 31 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/craft/src/components/layout/Container.tsx b/craft/src/components/layout/Container.tsx index 22b39fe..7a2e7b9 100644 --- a/craft/src/components/layout/Container.tsx +++ b/craft/src/components/layout/Container.tsx @@ -20,6 +20,17 @@ interface ContainerProps { contentWidth?: 'boxed' | 'full'; } +// Map textAlign to a flex alignItems value so block-level children (images, +// columns, sections) align horizontally — textAlign alone only affects inline +// content. Returns undefined when no alignment is set so we leave layout as +// normal block flow. +const flexAlignFromTextAlign = (textAlign: CSSProperties['textAlign']): CSSProperties => { + if (textAlign === 'center') return { display: 'flex', flexDirection: 'column', alignItems: 'center' }; + if (textAlign === 'right') return { display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }; + if (textAlign === 'left') return { display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }; + return {}; +}; + export const Container: UserComponent = ({ style = {}, tag = 'div', @@ -29,14 +40,16 @@ export const Container: UserComponent = ({ }) => { const { connectors: { connect, drag } } = useNode(); + const needsBoxedWrapper = contentWidth === 'boxed'; + const flexStyles = flexAlignFromTextAlign(style.textAlign); + const outerStyle: CSSProperties = { minHeight: '40px', ...style, ...(fullWidth ? { width: '100vw', marginLeft: 'calc(-50vw + 50%)' } : {}), + ...(needsBoxedWrapper ? {} : flexStyles), }; - const needsBoxedWrapper = contentWidth === 'boxed'; - const el = React.createElement( tag, { @@ -45,7 +58,7 @@ export const Container: UserComponent = ({ 'data-craft-container': 'true', }, needsBoxedWrapper - ? React.createElement('div', { style: { maxWidth: '1200px', margin: '0 auto' } }, children) + ? React.createElement('div', { style: { maxWidth: '1200px', margin: '0 auto', ...flexStyles } }, children) : children, ); @@ -306,7 +319,13 @@ Container.craft = { (Container as any).toHtml = (props: ContainerProps, childrenHtml: string) => { const tag = props.tag || 'div'; - const outerCss: CSSProperties = { ...props.style }; + const isBoxed = props.contentWidth === 'boxed'; + const flexStyles = flexAlignFromTextAlign(props.style?.textAlign); + + const outerCss: CSSProperties = { + ...props.style, + ...(isBoxed ? {} : flexStyles), + }; if (props.fullWidth) { outerCss.width = '100vw'; @@ -315,8 +334,8 @@ Container.craft = { const styleStr = cssPropsToString(outerCss); - if (props.contentWidth === 'boxed') { - const innerStyle = cssPropsToString({ maxWidth: '1200px', margin: '0 auto' }); + if (isBoxed) { + const innerStyle = cssPropsToString({ maxWidth: '1200px', margin: '0 auto', ...flexStyles }); return { html: `<${tag}${styleStr ? ` style="${styleStr}"` : ''}>${childrenHtml}` }; }