Component render/toHtml now use var(--wsb-*) instead of hex so Site Design palette changes reach FeaturesGrid, Testimonials, Accordion, PricingTable, CTA/CallToAction, forms, Gallery, Tabs and others. Exemption lists removed. Refs #44 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
78 lines
3.6 KiB
TypeScript
78 lines
3.6 KiB
TypeScript
import React from 'react';
|
|
import { describe, test, expect, afterEach } from 'vitest';
|
|
import { renderEditorHarness, EditorHarness } from '../../test-utils/editorHarness';
|
|
import { SiteDesignProvider, useSiteDesign, SiteDesignContextValue, DEFAULT_SITE_DESIGN } from '../../state/SiteDesignContext';
|
|
import { CanvasTokenStyle } from '../../editor/CanvasTokenStyle';
|
|
import { buildNodeTree } from '../../utils/craft-tree';
|
|
import { templateComponentToTreeNode } from '../../templates/apply-template';
|
|
import { exportBodyHtml, exportToHtml } from '../../utils/html-export';
|
|
|
|
/**
|
|
* #44 component-tokens, real-editor harness: a page of FeaturesGrid + PricingTable +
|
|
* Testimonials (default props). Their colours must be token references, the canvas
|
|
* token <style> must follow a Site Design change, and the export must reference tokens
|
|
* (and define the changed primary once, in :root) rather than carry the old hex.
|
|
*/
|
|
let h: EditorHarness | null = null;
|
|
afterEach(() => {
|
|
h?.unmount();
|
|
h = null;
|
|
});
|
|
|
|
const DesignProbe: React.FC<{ out: { current: SiteDesignContextValue | null } }> = ({ out }) => {
|
|
out.current = useSiteDesign();
|
|
return null;
|
|
};
|
|
|
|
const OLD_HEX = ['#f8fafc', '#e2e8f0', '#18181b', '#64748b', '#4b5563', '#374151', '#bbf7d0', '#facc15', '#f59e0b'];
|
|
|
|
describe('component colours follow Site Design (real editor harness)', () => {
|
|
test('FeaturesGrid + PricingTable + Testimonials: canvas vars follow primary; export references tokens', () => {
|
|
h = renderEditorHarness();
|
|
const ctx: { current: SiteDesignContextValue | null } = { current: null };
|
|
h.mountChild(
|
|
<SiteDesignProvider>
|
|
<CanvasTokenStyle />
|
|
<DesignProbe out={ctx} />
|
|
</SiteDesignProvider>,
|
|
);
|
|
h.act(() => {
|
|
for (const type of ['FeaturesGrid', 'PricingTable', 'Testimonials']) {
|
|
h!.actions.addNodeTree(
|
|
buildNodeTree(h!.query, templateComponentToTreeNode({ type, props: {} } as any)),
|
|
'ROOT',
|
|
);
|
|
}
|
|
});
|
|
|
|
// Canvas: the editor-rendered DOM carries var() refs (jsdom keeps them verbatim).
|
|
const clone = h.container.cloneNode(true) as HTMLElement;
|
|
clone.querySelectorAll('style').forEach((el) => el.remove()); // token definitions legitimately hold hex
|
|
const dom = clone.innerHTML;
|
|
expect(dom).toContain('var(--wsb-border)');
|
|
expect(dom).toContain('var(--wsb-muted)');
|
|
expect(dom).toContain('var(--wsb-primary)');
|
|
for (const hex of OLD_HEX) expect(dom.toLowerCase(), `canvas ${hex}`).not.toContain(hex);
|
|
|
|
// Canvas custom properties follow Site Design.
|
|
const canvasVars = () => document.querySelector('style[data-wsb-canvas-tokens]')!.textContent ?? '';
|
|
expect(canvasVars()).toContain('--wsb-primary:#3b82f6');
|
|
h.act(() => ctx.current!.updateDesign({ primaryColor: '#c0ffee', mutedTextColor: '#123456' }));
|
|
expect(canvasVars()).toContain('--wsb-primary:#c0ffee');
|
|
expect(canvasVars()).toContain('--wsb-muted:#123456');
|
|
|
|
// Export: tokens, no old design hex in the body.
|
|
const ser = h.getSerialized();
|
|
const { html } = exportBodyHtml(ser);
|
|
expect(html).toContain('var(--wsb-primary)');
|
|
expect(html).toContain('var(--wsb-warning)');
|
|
for (const hex of OLD_HEX) expect(html.toLowerCase(), `export ${hex}`).not.toContain(hex);
|
|
|
|
// Restyling Site Design changes only :root, never the body markup.
|
|
const a = exportToHtml(ser, { design: { ...DEFAULT_SITE_DESIGN } }).html;
|
|
const b = exportToHtml(ser, { design: { ...DEFAULT_SITE_DESIGN, primaryColor: '#c0ffee', mutedTextColor: '#123456' } }).html;
|
|
expect(b).toContain('--wsb-muted:#123456');
|
|
expect(b.slice(b.indexOf('<body'))).toBe(a.slice(a.indexOf('<body')));
|
|
});
|
|
});
|