@ffsm/snapshot
v1.2.0
Published
React snapshot utilities for capturing and measuring DOM elements
Maintainers
Readme
@ffsm/snapshot
React snapshot utilities for capturing and measuring DOM elements.
Installation
npm install @ffsm/snapshot
# or
yarn add @ffsm/snapshotUsage
useSnapshot Hook
import { useSnapshot } from '@ffsm/snapshot';
function MyComponent() {
const containerRef = useSnapshot(
(size, error) => {
if (error) {
console.error('Measurement failed:', error);
} else if (size) {
console.log('Element dimensions:', size);
// size.width and size.height are available
}
},
{
delay: 100,
lowerWidthBound: 300,
lowerHeightBound: 200,
retryInit: 3,
observer: true,
onRetry: () => console.log('Retrying measurement...'),
validate: (size) => {
// Custom validation: ensure aspect ratio is reasonable
const ratio = size.width / size.height;
return ratio >= 1.0 && ratio <= 3.0;
}
}
);
return <div ref={containerRef}>Content to measure</div>;
}Snapshot Component
import { Snapshot } from '@ffsm/snapshot';
function MyComponent() {
return (
<Snapshot
options={{
onSnapshot: (size, error) => {
if (error) {
console.error('Measurement failed:', error);
} else if (size) {
console.log(`Measured: ${size.width}x${size.height}`);
}
},
delay: 100,
observer: true
}}
style={{ border: '1px solid #ccc', padding: '10px' }}
>
<h1>Content to measure</h1>
<p>This container will be measured automatically</p>
</Snapshot>
);
}Simple Usage
import { useSnapshot, Snapshot } from '@ffsm/snapshot';
// Hook approach
function SimpleHook() {
const ref = useSnapshot((size, error) => {
if (size) {
console.log(`Size: ${size.width}x${size.height}`);
}
});
return <div ref={ref}>Content</div>;
}
// Component approach
function SimpleComponent() {
return (
<Snapshot options={{ onSnapshot: (size) => console.log(size) }}>
<div>Content</div>
</Snapshot>
);
}
// Advanced validation example
function ValidatedComponent() {
const ref = useSnapshot(
(size, error) => {
if (error) {
console.error('Validation failed:', error);
} else if (size) {
console.log('Valid dimensions:', size);
}
},
{
lowerWidthBound: 400,
lowerHeightBound: 300,
validate: (size) => {
// Custom validation: minimum area and reasonable aspect ratio
const area = size.width * size.height;
const ratio = size.width / size.height;
return area >= 120000 && ratio >= 0.75 && ratio <= 2.0;
}
}
);
return <div ref={ref}>Content with custom validation</div>;
}withSnapshot HOC
import { withSnapshot } from '@ffsm/snapshot';
function MyComponent({ snapshot, error, containerProps }) {
if (error) {
return <div>Measurement error: {error}</div>;
}
return (
<div>
{snapshot ? (
<p>Dimensions: {snapshot.width}x{snapshot.height}</p>
) : (
<p>Measuring...</p>
)}
</div>
);
}
const EnhancedComponent = withSnapshot(MyComponent, {
delay: 100,
lowerWidthBound: 300,
lowerHeightBound: 200,
observer: true,
validate: (size) => size.width > size.height // Only landscape orientations
});
// Usage
function App() {
return (
<EnhancedComponent
containerProps={{
style: { border: '1px solid #ccc' }
}}
/>
);
}API
useSnapshot(measured, options?)
Hook for measuring DOM element dimensions with automatic retry and resize observation.
Parameters
measured: (size: SnapshotSize | null, error: SnapshotError | null) => void- Callback function that receives measurement results
size: Object withwidthandheightproperties, ornullif measurement failederror: Error type if measurement failed, ornullif successful
options?: UseSnapshotOptions(optional)delay?: number- Delay in milliseconds before taking measurements (default: 0)lowerWidthBound?: number- Minimum width required for valid measurements (default: 320)lowerHeightBound?: number- Minimum height required for valid measurements (default: 0)retryInit?: number- Number of retry attempts (default: 1)loading?: boolean- Whether the hook is in loading stateerror?: SnapshotError | null- Current error stateobserver?: boolean- Use ResizeObserver for automatic re-measurements (default: true)onRetry?: () => void- Callback function called on retry attemptsvalidate?: (size: SnapshotSize) => boolean- Custom validation function for size measurements
Returns
containerRef: RefObject<HTMLDivElement>- Ref to attach to the element (parent will be measured)
Snapshot Component
React component that automatically measures its dimensions and provides them via callback.
Props
options?: WithSnapshotOptions- Configuration options for measurementonSnapshot?: (size: SnapshotSize | null, error: SnapshotError | null) => void- Measurement callback- All other options from
UseSnapshotOptions
...divProps- All standard HTML div attributes (className, style, etc.)children- Content to be wrapped and measured
Usage
<Snapshot
options={{ onSnapshot: (size) => console.log(size) }}
className="my-wrapper"
>
Content to measure
</Snapshot>withSnapshot(Component, options?)
Higher-order component for adding snapshot functionality to React components.
Parameters
Component: ComponentType<WithSnapshotProps<P>>- Component to enhanceoptions?: WithSnapshotOptions- Same options as useSnapshot hook plus onSnapshot callback
Enhanced Component Props
The wrapped component receives additional props:
snapshot?: SnapshotSize | null- Current measured dimensionserror?: SnapshotError | null- Current error statecontainerProps?: HTMLAttributes<HTMLDivElement>- Props for the wrapper container
Error Types
SnapshotError.PARENT_NOT_FOUND- Parent element not found in DOMSnapshotError.INVALID_SIZE- Element size is below the specified bounds
License
MIT
