- 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>
Adopted in BackgroundSectionStylePanel, ButtonStylePanel, ContainerStylePanel,
FormStylePanel, GenericPropsEditor, HeroStylePanel, ImageStylePanel,
MediaStylePanel, NavStylePanel, SectionTypePanel, SocialStylePanel,
TextStylePanel — only where the inline setProp/setPropStyle were behaviorally
identical to the hook. PricingStylePanel and FeaturesEditor keep their own
array-mutation logic since it differs. Behavior-preserving (task E4.1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Container.craft.props collected cssId/cssClass since before Phase E1 but
nothing rendered or exported them. Add live "CSS ID" / "CSS Class" text
inputs to ContainerStylePanel (guarded on nodeProps.cssId/cssClass
!== undefined) and emit id=/class= in both the editor render and toHtml.
cssId takes precedence over the existing anchorId prop when both are set
(only one id attribute can be emitted); anchorId is used as a fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuilt the visual site builder from scratch using Craft.js, React 18,
and TypeScript. The new editor renders directly in the DOM (no iframe),
supports 40+ components, multi-page with shared header/footer, 16
templates, full-spectrum color/gradient controls, custom head code
injection, save/publish workflow, and auto-save.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>