How to Capture All Component States (Hover, Active, Scroll-Dependent) During Extraction
To capture all component states during extraction, systematically trigger hover, click, and scroll interactions while recording computed styles before and after each state change, then document these findings in the repository's Markdown specification files.
The JCodesMore/ai-website-cloner-template repository provides a structured inspection workflow designed to clone websites with pixel-perfect accuracy. Capturing every visual state—including default, hover, active, focus, disabled, loading, error, empty, and scroll-driven styles—is essential for generating components that faithfully reproduce the original site's interactive behavior.
Set Up the Inspection Environment
Begin by opening the target page in Chrome or any Chromium-based browser. Install and enable the Chrome MCP (Multi-Component Profiler) extension included with the repository, which allows you to query computed styles and trigger interaction states programmatically.
Perform a Systematic Hover-Sweep
Iterate over every DOM node that could have a hover state, including buttons, cards, links, and menus. For each element, record the default computed styles, trigger the hover state via MCP, then capture the modified styles.
// Helper functions like this leverage the `cn` utility (see src/lib/utils.ts)
async function captureHoverState(el: Element) {
// Record default values
const before = getComputedStyle(el);
// Trigger hover via MCP
await triggerHover(el); // ← defined in the MCP docs
const after = getComputedStyle(el);
return { selector: el.tagName, before, after };
}
Save the before/after values together with the exact trigger description, such as "hover on .card-cta", to ensure precise reconstruction later.
Capture Active and Click-Driven States
Use the same MCP script to click elements and read the resulting computed styles. Pay special attention to transition timing properties like transition-duration and transition-delay, as these define how the component animates between states.
Record Scroll-Dependent Styles
Identify elements whose appearance changes based on scroll position, such as sticky headers or reveal-on-scroll cards. For each relevant scroll offset, execute:
await window.scrollTo(0, scrollY);
await waitForIdle(); // ensure Layout/PAINT are done
const styles = getComputedStyle(targetEl);
Document the scroll offset and any IntersectionObserver thresholds used, such as rootMargin "-30% 0px", to replicate scroll-driven animations accurately.
Export the Component Specification
Assemble all captured data into Markdown spec files within docs/research/. The repository expects structured documentation in files like COMPONENT_INVENTORY.md and INTERACTION_PATTERNS.md, as outlined in the Inspection Guide.
Each component entry must specify:
- Name – a sensible React component name
- Structure – HTML hierarchy
- Variants – size and color differences
- States – default, hover, active, disabled, loading, error, empty
- Responsive breakpoints – adaptation behavior
- Triggers – exact mechanisms (click, hover, scroll offset, time)
Validate Captured States
Run the visual diff step in the /clone-website pipeline to compare the generated UI against original screenshots. If any state is missing, repeat the sweep for that specific element until the visual output matches the source.
Automate State Capture for Large Sites
The repository provides a ready-to-run Hover sweep script defined in .windsurf/workflows/clone-website.md and .github/skills/clone-website/SKILL.md. Hook this automation into scripts/sync-skills.mjs to generate per-section builder agents that each receive the full multi-state specification.
Reusable State Capture Implementation
For programmatic extraction, implement a helper like this in src/lib/stateCapture.ts:
// src/lib/stateCapture.ts – minimal helper used by the MCP scripts
export async function captureMultiState(
el: Element,
triggers: { type: 'hover' | 'click' | 'scroll'; value?: number }[]
) {
const result: Record<string, CSSStyleDeclaration> = {};
// default
result['default'] = getComputedStyle(el);
for (const t of triggers) {
switch (t.type) {
case 'hover':
await triggerHover(el);
result['hover'] = getComputedStyle(el);
break;
case 'click':
await triggerClick(el);
result['active'] = getComputedStyle(el);
break;
case 'scroll':
await window.scrollTo(0, t.value ?? 0);
await waitForIdle();
result[`scroll_${t.value}`] = getComputedStyle(el);
break;
}
}
return result;
}
Usage within a builder agent (as documented in docs/research/INTERACTION_PATTERNS.md):
import { captureMultiState } from '@/lib/stateCapture';
const btn = document.querySelector('.primary-button')!;
const styles = await captureMultiState(btn, [
{ type: 'hover' },
{ type: 'click' },
{ type: 'scroll', value: 100 },
]);
// Export to Markdown
await writeFile(
'docs/research/COMPONENT_INVENTORY.md',
`### Button – Primary\n\`\`\`json\n${JSON.stringify(styles, null, 2)}\n\`\`\``
);
Essential Files for State Extraction
Reference these key files when implementing your capture workflow:
docs/research/INSPECTION_GUIDE.md– The master checklist for what to capture, including hover-sweep and scroll-dependent states.github/skills/clone-website/SKILL.md– Provides the exact wording that agents read to ensure they extract all states.windsurf/workflows/clone-website.md– Describes the practical "Hover sweep" process and MCP trigger mechanismssrc/lib/stateCapture.ts– Location for the central helper that grabs computed styles across statesREADME.md(section How It Works) – Explains the multi-phase pipeline where captured states feed the builder agents
Summary
- Capture nine distinct states for each component: default, hover, active, focus, disabled, loading, error, empty, and scroll-driven
- Use the Chrome MCP extension to programmatically trigger hover and click states while recording computed styles
- Document scroll positions and IntersectionObserver thresholds for elements with scroll-dependent appearance
- Store specifications in
docs/research/COMPONENT_INVENTORY.mdandINTERACTION_PATTERNS.mdusing the prescribed Markdown format - Validate extraction by running the
/clone-websitevisual diff pipeline against original screenshots - Automate large sites using the Hover sweep script integrated with
scripts/sync-skills.mjs
Frequently Asked Questions
What specific component states must I capture during extraction?
You must record default, hover, active, focus, disabled, loading, error, empty, and scroll-dependent styles for each element. According to the repository's docs/research/INSPECTION_GUIDE.md, capturing this complete set ensures the cloned components behave identically to the original across all user interactions.
How do I programmatically trigger hover states when the MCP extension isn't available?
While the repository recommends the Chrome MCP extension for triggerHover() functionality, you can simulate hover states by dispatching native JavaScript events or using browser DevTools Protocol (CDP) commands. The captureHoverState helper in your extraction scripts should compare getComputedStyle() results before and after triggering these events to capture the computed CSS differences.
Where should I store the captured state data?
Export all captured state data to Markdown files under docs/research/, specifically COMPONENT_INVENTORY.md for structural hierarchies and INTERACTION_PATTERNS.md for behavioral specifications. Each entry must include the component name, variants, all nine possible states, responsive breakpoints, and precise trigger mechanisms.
How do I handle scroll-dependent states that use Intersection Observer?
For scroll-dependent elements, record the exact scroll offsets where visual changes occur using window.scrollTo() followed by waitForIdle() to ensure layout completion. Document any IntersectionObserver configurations, such as rootMargin values like "-30% 0px", alongside the computed styles at each threshold so builder agents can replicate the scroll-triggered animations accurately.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →