@ygo/svelte-grab
v0.0.2
Published
Grab any element in your Svelte app and give it to Cursor, Claude Code, or other AI coding agents.
Readme
Svelte Grab
Grab any element in your Svelte app and give it to Cursor, Claude Code, or other AI coding agents.
Svelte Grab is an interactive developer tool that lets you select any element in your Svelte application and copy its context (HTML structure + source code location) to your clipboard, ready to paste into AI coding assistants.
Features
- Keyboard Activation - Hold
Ctrl/Cmd + Cto activate grab mode - Element Detection - Real-time element highlighting as you hover
- Component Detection - Shows Svelte component names and source file locations
- Drag Selection - Select multiple elements by dragging
- Custom Notes - Add context notes when grabbing elements
- Visual Feedback - Selection boxes, labels, crosshairs, and success indicators
- Theming - Fully customizable colors and appearance
- Shadow DOM Isolation - UI overlays won't interfere with your app's styles
Installation
From npm (public)
# Using bun
bun add svelte-grab
# Using npm
npm install svelte-grab
# Using pnpm
pnpm add svelte-grab
# Using yarn
yarn add svelte-grabQuick Start
Method 1: Script Tag (Easiest)
Add the script tag to your HTML. It auto-initializes and attaches to window.SvelteGrab:
<script src="https://unpkg.com/svelte-grab/dist/index.global.js"></script>To disable auto-initialization:
<script src="https://unpkg.com/svelte-grab/dist/index.global.js" data-auto-init="false"></script>
<script>
// Initialize manually with custom options
window.SvelteGrab = SvelteGrab.init({
keyHoldDuration: 300,
});
</script>Method 2: ES Module Import
import { init } from 'svelte-grab';
// Initialize with default options
const svelteGrab = init();
// Or with custom options
const svelteGrab = init({
keyHoldDuration: 200,
theme: {
hue: 200, // Blue theme
},
onCopySuccess: (elements, content) => {
console.log('Copied:', content);
},
});Method 3: SvelteKit Integration
In your root +layout.svelte:
<script>
import { onMount } from 'svelte';
import { dev } from '$app/environment';
onMount(async () => {
if (dev) {
const { init } = await import('svelte-grab');
init();
}
});
</script>
<slot />Usage
- Activate: Hold
Ctrl + C(Windows/Linux) orCmd + C(Mac) for 200ms - Select: Click on any element to copy its context
- Drag Select: Click and drag to select multiple elements
- Add Notes: Press
Enterwhile activated to add a custom note - Deactivate: Release the keys or press
Escape
The copied content includes:
- HTML structure of the selected element
- Source code location (file path and line number)
- Any custom notes you added
API Reference
init(options?: Options): SvelteGrabAPI
Initializes Svelte Grab with optional configuration.
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| enabled | boolean | true | Enable/disable Svelte Grab |
| keyHoldDuration | number | 200 | Milliseconds to hold keys before activation |
| allowActivationInsideInput | boolean | true | Allow activation when focused on input fields |
| theme | Theme | See below | Customize appearance |
| onActivate | () => void | - | Called when grab mode activates |
| onDeactivate | () => void | - | Called when grab mode deactivates |
| onElementHover | (element: Element) => void | - | Called when hovering over an element |
| onElementSelect | (element: Element) => void | - | Called when an element is selected |
| onBeforeCopy | (elements: Element[]) => void | - | Called before copying |
| onAfterCopy | (elements: Element[], success: boolean) => void | - | Called after copy attempt |
| onCopySuccess | (elements: Element[], content: string) => void | - | Called on successful copy |
| onCopyError | (error: Error) => void | - | Called on copy error |
| onStateChange | (state: SvelteGrabState) => void | - | Called on any state change |
SvelteGrabAPI
The init() function returns an API object:
interface SvelteGrabAPI {
activate(): void; // Programmatically activate grab mode
deactivate(): void; // Programmatically deactivate grab mode
toggle(): void; // Toggle grab mode
isActive(): boolean; // Check if grab mode is active
dispose(): void; // Clean up and remove all event listeners
copyElement(elements: Element | Element[]): Promise<boolean>; // Copy specific elements
getState(): SvelteGrabState; // Get current state
updateTheme(theme: DeepPartial<Theme>): void; // Update theme at runtime
getTheme(): Theme; // Get current theme
}Theme Configuration
Customize the appearance:
init({
theme: {
hue: 150, // Green theme (0-360)
selectionBox: {
enabled: true,
color: 'rgba(0, 255, 0, 0.3)',
borderRadius: '4px',
},
dragBox: {
enabled: true,
color: 'rgba(0, 255, 0, 0.2)',
},
grabbedBoxes: {
enabled: true,
color: 'rgba(0, 255, 0, 0.5)',
},
elementLabel: {
enabled: true,
backgroundColor: '#1a1a1a',
textColor: '#ffffff',
borderColor: '#333333',
cursorOffset: 16,
},
successLabels: {
enabled: true,
},
crosshair: {
enabled: true,
color: 'rgba(255, 255, 255, 0.5)',
},
inputOverlay: {
enabled: true,
},
},
});Exported Utilities
import {
// Initialization
init,
initSvelteGrab, // Alias for init
// Theme utilities
DEFAULT_THEME,
mergeTheme,
deepMergeTheme,
// Instrumentation utilities
getHTMLPreview,
formatStack,
getStack,
getNearestComponentName,
isInstrumentationActive,
// State stores (for advanced usage)
isActivated,
isDragging,
isCopying,
mouseX,
mouseY,
targetElement,
selectionBounds,
dragBounds,
} from 'svelte-grab';Examples
Basic Usage
import { init } from 'svelte-grab';
const grab = init();
// Later, when done:
grab.dispose();With Callbacks
import { init } from 'svelte-grab';
const grab = init({
onActivate: () => console.log('Grab mode activated'),
onDeactivate: () => console.log('Grab mode deactivated'),
onCopySuccess: (elements, content) => {
console.log(`Copied ${elements.length} element(s)`);
// Send to your AI assistant API
sendToAssistant(content);
},
onCopyError: (error) => {
console.error('Copy failed:', error);
},
});Programmatic Control
import { init } from 'svelte-grab';
const grab = init({ keyHoldDuration: 0 }); // Instant activation
// Activate via button
document.getElementById('grab-btn').addEventListener('click', () => {
grab.toggle();
});
// Copy a specific element
const element = document.querySelector('.my-component');
await grab.copyElement(element);Dynamic Theme Updates
import { init } from 'svelte-grab';
const grab = init();
// Switch to dark mode theme
grab.updateTheme({
elementLabel: {
backgroundColor: '#000000',
textColor: '#ffffff',
},
});How It Works
Svelte Grab uses Svelte's built-in debug events and __svelte_meta property to:
- Detect Svelte components in your application
- Track the source file locations of components
- Build a component hierarchy for each DOM element
When you select an element, it:
- Captures the HTML structure
- Walks up the component tree to find source locations
- Formats everything into a clipboard-friendly format
Requirements
- Svelte 4.x
- Modern browser with Clipboard API support
Development
# Install dependencies
bun install
# Build the package
bun run build
# Watch mode
bun run dev
# Run the playground
bun run dev:playground
# Lint
bun run lint
# Format
bun run format