feat(builder): containers package -- vertical alignment + box-model/anim/vis rollout
- ColumnLayout: exposes style.alignItems on its flex ROW (aligns uneven columns) -- render/toHtml already spread `style` onto the row div, so this is a craft.props default + panel control addition, no structural change. - Container/Section: root element is now unconditionally display:flex; flex-direction:column (both editor render and toHtml), so the new Vertical Alignment control maps to style.justifyContent, paired with a Min Height (NumericUnitInput) control on style.minHeight. Default justify-content/align-items reproduce ordinary block-flow stacking, so this is a visual no-op for existing published content. Works in both normal and "boxed" (contentWidth) modes -- the boxed inner wrapper's own margin:0-auto horizontal centering is preserved via flex auto-margin override semantics. - ContainerStylePanel (serves Container/Section/Columns) distinguishes the Columns case from Container/Section via nodeProps.columns/split presence (no typeName plumbing needed) to pick align-items vs justify-content for the shared Vertical Alignment control. - All 3 owned components: added margin/padding (per-side)/border/box-shadow/ opacity style defaults + AnimationControl/VisibilityControl-backed animation/animationDelay/hideOnDesktop/hideOnTablet/hideOnMobile props. New containerBoxModel.tsx (package-local, not shared.tsx) DRYs the box-model + border/effects + animation/visibility panel sections across the single shared ContainerStylePanel, mirroring the sibling media package's mediaBoxModel.tsx. - Tests: extended all 3 *.toHtml.test.ts files (align-items/justify-content/ min-height emission, box-model style emission, craft.props presence). 673 tests green, tsc + vite build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,18 @@ const flexAlignFromTextAlign = (textAlign: CSSProperties['textAlign']): CSSPrope
|
||||
return {};
|
||||
};
|
||||
|
||||
// Container is ALWAYS display:flex/flex-direction:column at its root (both
|
||||
// in the editor render below and in toHtml) so that `style.justifyContent`
|
||||
// (the new Vertical Alignment control, paired with `style.minHeight`) has an
|
||||
// axis to act on. This is a no-op visually for existing content: a column
|
||||
// flex container with default `justify-content:flex-start` and
|
||||
// `align-items:stretch` reproduces ordinary block-flow stacking (children
|
||||
// stack top-to-bottom, full width) byte-for-byte, so nothing published
|
||||
// before this feature shipped changes appearance. `flexAlignFromTextAlign`
|
||||
// above still supplies `alignItems` (cross-axis, i.e. horizontal position)
|
||||
// from `textAlign` independently -- the two controls act on orthogonal axes
|
||||
// and don't conflict.
|
||||
|
||||
export const Container: UserComponent<ContainerProps> = ({
|
||||
style = {},
|
||||
tag = 'div',
|
||||
@@ -60,6 +72,8 @@ export const Container: UserComponent<ContainerProps> = ({
|
||||
const flexStyles = flexAlignFromTextAlign(style.textAlign);
|
||||
|
||||
const outerStyle: CSSProperties = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
minHeight: '40px',
|
||||
...style,
|
||||
...(fullWidth ? { width: '100vw', marginLeft: 'calc(-50vw + 50%)' } : {}),
|
||||
@@ -93,13 +107,27 @@ export const Container: UserComponent<ContainerProps> = ({
|
||||
Container.craft = {
|
||||
displayName: 'Container',
|
||||
props: {
|
||||
style: { padding: '20px', minHeight: '100px' },
|
||||
style: {
|
||||
padding: '20px',
|
||||
minHeight: '100px',
|
||||
justifyContent: '',
|
||||
marginTop: '', marginRight: '', marginBottom: '', marginLeft: '',
|
||||
paddingTop: '', paddingRight: '', paddingBottom: '', paddingLeft: '',
|
||||
border: 'none',
|
||||
boxShadow: 'none',
|
||||
opacity: '1',
|
||||
},
|
||||
tag: 'div',
|
||||
fullWidth: false,
|
||||
contentWidth: 'full',
|
||||
anchorId: '',
|
||||
cssId: '',
|
||||
cssClass: '',
|
||||
animation: '',
|
||||
animationDelay: '0',
|
||||
hideOnDesktop: false,
|
||||
hideOnTablet: false,
|
||||
hideOnMobile: false,
|
||||
},
|
||||
rules: {
|
||||
canDrag: () => true,
|
||||
@@ -116,6 +144,8 @@ Container.craft = {
|
||||
const flexStyles = flexAlignFromTextAlign(props.style?.textAlign);
|
||||
|
||||
const outerCss: CSSProperties = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
...props.style,
|
||||
...(isBoxed ? {} : flexStyles),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user