Paste Event Scope Control
December 10, 2025 ยท View on GitHub
Control how paste events are handled when using svelte-image-input components.
Overview
By default, ImageLoader listens for paste events anywhere on the page (window-level). This is convenient for single-component usage but can cause issues when multiple components are used or when other paste targets exist on the page.
The pasteScope prop allows you to control whether paste events are handled at the window level or only when the component is focused.
Props
ImageLoader
pasteScope?: 'window' | 'component'(default:'window')
ImageInput
The ImageInput component passes the pasteScope prop to its internal ImageLoader.
Behavior
Window Scope (Default)
When pasteScope="window" (or not specified):
- Paste events anywhere on the page trigger image loading
- Convenient for single-component usage
- Works even when component is not focused
- May conflict with other paste targets (text inputs, textareas)
- Multiple components all respond to paste events
<ImageLoader onImageLoaded={handleImageLoaded} />
<!-- or -->
<ImageLoader onImageLoaded={handleImageLoaded} pasteScope="window" />
Component Scope
When pasteScope="component":
- Paste events only work when the component is focused
- Better for multiple components on the same page
- No conflicts with other paste targets
- Component must be clicked or focused first
- Only the focused component responds to paste
<ImageLoader
onImageLoaded={handleImageLoaded}
pasteScope="component"
/>
Usage Examples
Single Component (Default)
For a single component, the default window scope is usually best:
<ImageInput bind:url />
<!-- Paste works anywhere on the page -->
Multiple Components
When using multiple components, use component scope to avoid conflicts:
<div class="image-editors">
<div>
<h3>Profile Picture</h3>
<ImageInput bind:url1 pasteScope="component" />
</div>
<div>
<h3>Cover Photo</h3>
<ImageInput bind:url2 pasteScope="component" />
</div>
</div>
Now each component only responds to paste when it's focused.
Mixed Usage
You can mix window and component scope:
<!-- Global paste handler (only one should use window scope) -->
<ImageInput bind:url1 pasteScope="window" />
<!-- Component-specific paste handlers -->
<ImageInput bind:url2 pasteScope="component" />
<ImageInput bind:url3 pasteScope="component" />
With Other Paste Targets
When your page has text inputs or other paste targets, use component scope:
<div>
<input type="text" placeholder="Enter description..." />
<ImageInput
bind:url
pasteScope="component"
/>
</div>
This ensures pasting in the text input doesn't trigger image loading.
Focus Behavior
When using pasteScope="component":
- Clicking the component gives it focus
- Tab navigation can focus the component
- Paste works when the component or its children have focus
- Visual focus indicator appears (customizable via CSS)
Programmatic Focus
You can programmatically focus the component if needed:
<script>
import { ImageInput } from 'svelte-image-input';
let imageInputElement;
let url = '';
function focusImageInput() {
// Focus the component's drop area
imageInputElement?.querySelector('.drop-area')?.focus();
}
</script>
<button onclick={focusImageInput}>Focus Image Input</button>
<ImageInput bind:this={imageInputElement} bind:url pasteScope="component" />
Accessibility
When using component scope:
- The component becomes keyboard accessible (via
tabindex="0") - Focus indicators should be visible (customize via CSS)
- Screen readers will announce when the component is focused
- Users can navigate to the component using Tab key
Common Scenarios
Scenario 1: Single Image Upload
Use window scope (default):
<ImageInput bind:url />
Scenario 2: Multiple Image Uploads
Use component scope:
<ImageInput bind:url1 pasteScope="component" />
<ImageInput bind:url2 pasteScope="component" />
<ImageInput bind:url3 pasteScope="component" />
Scenario 3: Form with Text Inputs
Use component scope:
<form>
<input type="text" name="title" />
<textarea name="description"></textarea>
<ImageInput bind:url pasteScope="component" />
</form>
Scenario 4: Modal/Dialog
Use component scope:
<div class="modal">
<ImageInput bind:url pasteScope="component" />
</div>
Tips
- Default behavior: Window scope is convenient for most single-component use cases
- Multiple components: Always use component scope when multiple components exist
- Forms: Use component scope when other paste targets exist
- User experience: Component scope requires users to focus the component first, which may be less convenient but more predictable
Migration
If you're upgrading and want to maintain current behavior, no changes are needed - window scope is the default. To use component scope, simply add the prop:
<!-- Before (implicit window scope) -->
<ImageInput bind:url />
<!-- After (explicit window scope - same behavior) -->
<ImageInput bind:url pasteScope="window" />
<!-- After (component scope - new behavior) -->
<ImageInput bind:url pasteScope="component" />