From 045643d570deb6f0999fd7a31d07732e7e73f75a Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Wed, 7 Oct 2026 11:24:52 -0700 Subject: [PATCH] feat(site-builder): Section background and dividers default to bg token Refs #44 Co-Authored-By: Claude Sonnet 5.5 --- .../components/layout/Section.toHtml.test.ts | 20 +++++++++++++++++++ craft/src/components/layout/Section.tsx | 15 +++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/craft/src/components/layout/Section.toHtml.test.ts b/craft/src/components/layout/Section.toHtml.test.ts index 0d9afa8..168611f 100644 --- a/craft/src/components/layout/Section.toHtml.test.ts +++ b/craft/src/components/layout/Section.toHtml.test.ts @@ -148,3 +148,23 @@ describe('Section.craft.props exposes the vertical-alignment/box-model/animation expect(style.opacity).toBe('1'); }); }); + +describe('Section.toHtml palette token fallbacks (Refs #44)', () => { + test('divider fill falls back to the bg token (valid in an SVG style)', () => { + const { html } = toHtml({ topDivider: 'wave', bottomDivider: 'curve' }, ''); + expect(html.match(/fill:var\(--wsb-bg\)/g)).toHaveLength(2); + expect(html).not.toContain('#ffffff'); + }); + test('a new section (craft default props) paints the bg token and its divider colours', () => { + const p = (Section as any).craft.props; + expect(p.style.backgroundColor).toBe('var(--wsb-bg)'); + expect(p.topDividerColor).toBe('var(--wsb-bg)'); + const { html } = toHtml({ ...p, topDivider: 'wave' }, ''); + expect(html).toContain('background-color:var(--wsb-bg)'); + expect(html).toContain('fill:var(--wsb-bg)'); + }); + test('explicit divider colour wins', () => { + const { html } = toHtml({ topDivider: 'wave', topDividerColor: '#123456' }, ''); + expect(html).toContain('fill:#123456'); + }); +}); diff --git a/craft/src/components/layout/Section.tsx b/craft/src/components/layout/Section.tsx index a425e8f..d57366e 100644 --- a/craft/src/components/layout/Section.tsx +++ b/craft/src/components/layout/Section.tsx @@ -3,6 +3,7 @@ import { useNode, Element, UserComponent } from '@craftjs/core'; import { cssPropsToString } from '../../utils/style-helpers'; import { Container } from './Container'; import { escapeAttr, cssValue } from '../../utils/escape'; +import { tokenRef } from '../../utils/tokens'; /* ---------- Shape Divider SVG Paths ---------- */ @@ -74,7 +75,7 @@ const ShapeDivider: React.FC<{ style={{ width: '100%', height: '100%', - fill: color || '#ffffff', + fill: color || tokenRef('bg'), transform: isTop ? 'rotate(180deg)' : undefined, display: 'block', }} @@ -92,10 +93,10 @@ export const Section: UserComponent = ({ innerMaxWidth = '1200px', children, topDivider = 'none', - topDividerColor = '#ffffff', + topDividerColor = tokenRef('bg'), topDividerHeight = '50px', bottomDivider = 'none', - bottomDividerColor = '#ffffff', + bottomDividerColor = tokenRef('bg'), bottomDividerHeight = '50px', anchorId, }) => { @@ -158,7 +159,7 @@ Section.craft = { props: { style: { padding: '40px 0', - backgroundColor: '#ffffff', + backgroundColor: tokenRef('bg'), minHeight: '', justifyContent: '', marginTop: '', marginRight: '', marginBottom: '', marginLeft: '', @@ -169,10 +170,10 @@ Section.craft = { }, innerMaxWidth: '1200px', topDivider: 'none', - topDividerColor: '#ffffff', + topDividerColor: tokenRef('bg'), topDividerHeight: '50px', bottomDivider: 'none', - bottomDividerColor: '#ffffff', + bottomDividerColor: tokenRef('bg'), bottomDividerHeight: '50px', anchorId: '', animation: '', @@ -206,7 +207,7 @@ function buildDividerHtml( const isTop = position === 'top'; const h = height || '50px'; // Sanitized -- raw string-interpolation sink in the SVG `fill:${c}` below. - const c = cssValue(color) || '#ffffff'; + const c = cssValue(color) || tokenRef('bg'); const wrapperStyle = cssPropsToString({ position: 'absolute',