site-builder: dynamic CTAs, section anchors, edit-with-Sitesmith

Three related features:

1. Dynamic CTA buttons on HeroSimple, CTASection, CallToAction.
   New shared ctas[] array (text + href + variant + target) replaces the
   primary/secondary pair. Settings panel gets add/remove/reorder controls.
   Legacy fields stay readable for backwards compat — first user edit
   migrates the section onto the new array.

2. Anchor IDs on all layout/section components (Container, Section,
   BackgroundSection, ColumnLayout, plus 6 section blocks done by parallel
   subagent, plus Hero/CTA/CallToAction). Anchor input lives in the
   settings panel with an "auto from heading" button that walks the
   subtree for the first Heading.text. Renders as id="..." on the
   outermost element so #anchor URLs resolve.

3. Edit-with-Sitesmith targeted invocation. Right-click → "Ask Sitesmith"
   and a button at the top of the right-side settings panel both open the
   modal pre-targeted at the selected node. The node's serialized subtree
   is sent to the server; system prompt is augmented to require a patch
   with replace_node. Editor lifts modal state into a new SitesmithContext.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-25 12:43:28 -07:00
parent 7b747f775f
commit d0925d9e2d
24 changed files with 723 additions and 237 deletions
+12 -1
View File
@@ -6,18 +6,29 @@ import { WhpConfig } from './types';
import { EditorConfigProvider } from './state/EditorConfigContext';
import { SiteDesignProvider } from './state/SiteDesignContext';
import { PageProvider } from './state/PageContext';
import { SitesmithProvider, useSitesmithModal } from './state/SitesmithContext';
import { SitesmithModal } from './panels/sitesmith/SitesmithModal';
interface AppProps {
whpConfig: WhpConfig | null;
}
const SitesmithModalMount: React.FC = () => {
const { isOpen, target, close } = useSitesmithModal();
if (!isOpen) return null;
return <SitesmithModal target={target} onClose={close} />;
};
export const App: React.FC<AppProps> = ({ whpConfig }) => {
return (
<EditorConfigProvider config={whpConfig}>
<SiteDesignProvider>
<Editor resolver={componentResolver} enabled={true}>
<PageProvider>
<EditorShell />
<SitesmithProvider>
<EditorShell />
<SitesmithModalMount />
</SitesmithProvider>
</PageProvider>
</Editor>
</SiteDesignProvider>