Overview
The Options interface defines the configuration options you can pass to the init() function to customize React Grab’s behavior.
Type Definition
interface Options {
enabled?: boolean;
activationMode?: ActivationMode;
keyHoldDuration?: number;
allowActivationInsideInput?: boolean;
maxContextLines?: number;
activationKey?: ActivationKey;
getContent?: (elements: Element[]) => Promise<string> | string;
freezeReactUpdates?: boolean;
}
Properties
enabled
Whether React Grab is enabled on initialization.
Description:
- When
false, init() returns a no-op API where all methods are safe to call but perform no actions
- Useful for conditionally disabling React Grab in production or specific environments
- Cannot be changed after initialization via
setOptions() - use api.setEnabled() instead
Example:
const api = init({
enabled: process.env.NODE_ENV === 'development'
});
activationMode
activationMode
'toggle' | 'hold'
default:"'toggle'"
Controls how React Grab is activated.
Values:
'toggle': Press the activation key once to activate, press again to deactivate
'hold': Hold the activation key to activate, release to deactivate
Example:
const api = init({
activationMode: 'hold'
});
Notes:
- In
'toggle' mode, React Grab stays active until explicitly deactivated
- In
'hold' mode, you must continuously hold the activation key
keyHoldDuration
Duration in milliseconds to hold the activation key before activation.
Description:
- Prevents accidental activation when using the keyboard for normal copy operations
- Only applies when the activation key is initially pressed
- Default value:
100ms
Example:
const api = init({
keyHoldDuration: 200 // Require 200ms hold
});
Notes:
- If you press and release the key before this duration, normal copy behavior occurs
- If you hold for longer than this duration, React Grab activates
allowActivationInsideInput
Whether to allow activation when focus is inside an input field.
Description:
- When
true, React Grab can be activated even when an input, textarea, or contenteditable element is focused
- When
false, activation is blocked in these contexts to avoid interfering with normal text editing
Example:
const api = init({
allowActivationInsideInput: false
});
maxContextLines
Maximum number of surrounding context lines to include when copying elements.
Description:
- Controls how much surrounding code is included in the copied snippet
- Higher values provide more context but result in longer snippets
- Set to
0 to include only the element itself
Example:
const api = init({
maxContextLines: 5
});
Example Output:
With maxContextLines: 3:
<Container>
<Header />
<Button>Click me</Button> {/* Selected element */}
<Footer />
</Container>
With maxContextLines: 0:
<Button>Click me</Button> {/* Only the selected element */}
activationKey
Custom activation key configuration.
Type Definition:
type ActivationKey = string | ((event: KeyboardEvent) => boolean);
Description:
- Can be a string representing a keyboard code (e.g.,
'KeyG', 'KeyC')
- Can be a function that receives a
KeyboardEvent and returns true if it should activate
- By default, uses
Cmd+C (Mac) or Ctrl+C (Windows/Linux)
Example - String:
const api = init({
activationKey: 'KeyG' // Use Cmd+G / Ctrl+G
});
Example - Function:
const api = init({
activationKey: (event) => {
// Activate with Cmd+Shift+C / Ctrl+Shift+C
return event.code === 'KeyC' &&
event.shiftKey &&
(event.metaKey || event.ctrlKey);
}
});
Example - Alt Key:
const api = init({
activationKey: (event) => {
return event.code === 'KeyA' && event.altKey;
}
});
Notes:
- The modifier key (Cmd/Ctrl) is still required unless you override it in a custom function
- Using a commonly-used key combination may interfere with browser shortcuts
getContent
getContent
(elements: Element[]) => Promise<string> | string
Custom function to generate content when copying elements.
Parameters:
elements: Array of selected elements
Returns:
string or Promise<string>: The content to copy to clipboard
Description:
- Allows complete customization of copied content
- Can be synchronous or asynchronous
- Overrides the default snippet generation behavior
Example - HTML:
const api = init({
getContent: (elements) => {
return elements.map(el => el.outerHTML).join('\n');
}
});
Example - JSON:
const api = init({
getContent: (elements) => {
const data = elements.map(el => ({
tag: el.tagName.toLowerCase(),
id: el.id,
classes: Array.from(el.classList),
text: el.textContent?.trim()
}));
return JSON.stringify(data, null, 2);
}
});
Example - Async:
const api = init({
getContent: async (elements) => {
const snippets = await Promise.all(
elements.map(async (el) => {
const source = await api.getSource(el);
return `${source?.filePath || 'unknown'}:\n${el.outerHTML}`;
})
);
return snippets.join('\n\n');
}
});
freezeReactUpdates
Whether to freeze React state updates while React Grab is active.
Description:
- Prevents React components from re-rendering while selecting elements
- Stops UI changes that could interfere with element selection
- Uses React Fiber internals to pause component updates
Example:
const api = init({
freezeReactUpdates: false // Allow updates during selection
});
Notes:
- When
true, animations and state changes are paused during selection
- When
false, the UI can change while you’re selecting, which may be disorienting
- Recommended to keep this
true for best user experience
SettableOptions
The SettableOptions type is identical to Options except it excludes the enabled property:
interface SettableOptions extends Options {
enabled?: never;
}
Usage:
Used with api.setOptions() to update options after initialization:
const api = init();
api.setOptions({
activationMode: 'hold',
maxContextLines: 5
});
// Error: Cannot set 'enabled' via setOptions
// api.setOptions({ enabled: false });
// Instead, use:
api.setEnabled(false);
Complete Example
Here’s a comprehensive example using multiple options:
import { init } from 'react-grab';
const api = init({
// Only enable in development
enabled: process.env.NODE_ENV === 'development',
// Require holding the key
activationMode: 'hold',
keyHoldDuration: 150,
// Use Cmd+G / Ctrl+G instead
activationKey: 'KeyG',
// Allow activation in inputs
allowActivationInsideInput: true,
// Include more context
maxContextLines: 5,
// Freeze React during selection
freezeReactUpdates: true,
// Custom content generator
getContent: async (elements) => {
const snippets = await Promise.all(
elements.map(async (el) => {
const source = await api.getSource(el);
const displayName = api.getDisplayName(el);
return [
`// ${displayName} - ${source?.filePath}:${source?.lineNumber}`,
el.outerHTML
].join('\n');
})
);
return snippets.join('\n\n---\n\n');
}
});
Environment Configuration
You can also configure options via a script tag with data-react-grab-options:
<script
data-react-grab-options='{"activationMode": "hold", "maxContextLines": 5}'
></script>
These options are merged with options passed to init():
// Script tag options are merged with init() options
const api = init({
keyHoldDuration: 200 // Combined with script tag options
});