# How to Capture All Component States (Hover, Active, Scroll-Dependent) During Extraction

> Learn to capture component states like hover active and scroll during extraction. Systematically trigger interactions and record computed styles for accurate documentation in your repository.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-07-01

---

**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.

```typescript
// 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:

```typescript
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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/COMPONENT_INVENTORY.md) and [`INTERACTION_PATTERNS.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) and [`.github/skills/clone-website/SKILL.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/stateCapture.ts):

```tsx
// 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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docs/research/INTERACTION_PATTERNS.md)):

```tsx
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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.github/skills/clone-website/SKILL.md)** – Provides the exact wording that agents read to ensure they extract all states
- **[`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md)** – Describes the practical "Hover sweep" process and MCP trigger mechanisms
- **[`src/lib/stateCapture.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/lib/stateCapture.ts)** – Location for the central helper that grabs computed styles across states
- **[`README.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/README.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.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docs/research/COMPONENT_INVENTORY.md) and [`INTERACTION_PATTERNS.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/INTERACTION_PATTERNS.md) using the prescribed Markdown format
- **Validate extraction** by running the `/clone-website` visual 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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/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`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/COMPONENT_INVENTORY.md) for structural hierarchies and [`INTERACTION_PATTERNS.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/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.