@yhattav/react-component-cursor
Version:
A lightweight, TypeScript-first React library for creating beautiful custom cursors with SSR support, smooth animations, and zero dependencies. Perfect for interactive websites, games, and creative applications.
134 lines (122 loc) • 4.46 kB
text/typescript
import type { CustomCursorProps } from '../CustomCursor';
/**
* Development-only validation that gets tree-shaken in production
* Validates CustomCursor props and provides helpful error messages
*/
export function validateProps(props: CustomCursorProps): void {
// The entire function body gets removed in production builds
if (process.env.NODE_ENV !== 'development') return;
const {
id,
smoothness,
throttleMs,
zIndex,
offset,
containerRef,
centered,
showDevIndicator,
onMove,
onVisibilityChange,
} = props;
// Validate id (empty strings are allowed since we auto-generate UUIDs)
if (id !== undefined && typeof id !== 'string') {
console.error(
`CustomCursor: 'id' must be a string. Received: ${id} (${typeof id}). Note: empty strings are allowed and will auto-generate a UUID.`
);
}
// Validate smoothness
if (smoothness !== undefined) {
if (typeof smoothness !== 'number' || isNaN(smoothness)) {
console.error(
`CustomCursor: 'smoothness' must be a number. Received: ${smoothness} (${typeof smoothness})`
);
} else if (smoothness < 0) {
console.error(
`CustomCursor: 'smoothness' must be non-negative. Received: ${smoothness}. Use 1 for no smoothing, higher values for more smoothing.`
);
} else if (smoothness > 20) {
console.warn(
`CustomCursor: 'smoothness' value ${smoothness} is very high. Values above 20 may cause poor performance. Consider using a lower value.`
);
}
}
// Validate throttleMs
if (throttleMs !== undefined) {
if (typeof throttleMs !== 'number' || isNaN(throttleMs)) {
console.error(
`CustomCursor: 'throttleMs' must be a number. Received: ${throttleMs} (${typeof throttleMs})`
);
} else if (throttleMs < 0) {
console.error(
`CustomCursor: 'throttleMs' must be non-negative. Received: ${throttleMs}. Use 0 for no throttling.`
);
} else if (throttleMs > 100) {
console.warn(
`CustomCursor: 'throttleMs' value ${throttleMs} is quite high. This may make the cursor feel sluggish. Consider using a lower value (0-50ms).`
);
}
}
// Validate zIndex
if (zIndex !== undefined) {
if (typeof zIndex !== 'number' || isNaN(zIndex)) {
console.error(
`CustomCursor: 'zIndex' must be a number. Received: ${zIndex} (${typeof zIndex})`
);
} else if (!Number.isInteger(zIndex)) {
console.warn(
`CustomCursor: 'zIndex' should be an integer. Received: ${zIndex}`
);
}
}
// Validate offset
if (offset !== undefined) {
if (typeof offset !== 'object' || offset === null) {
console.error(
`CustomCursor: 'offset' must be an object with x and y properties. Received: ${offset}`
);
} else {
const { x, y } = offset as { x?: unknown; y?: unknown };
if (typeof x !== 'number' || isNaN(x)) {
console.error(
`CustomCursor: 'offset.x' must be a number. Received: ${x} (${typeof x})`
);
}
if (typeof y !== 'number' || isNaN(y)) {
console.error(
`CustomCursor: 'offset.y' must be a number. Received: ${y} (${typeof y})`
);
}
}
}
// Validate containerRef
if (containerRef !== undefined) {
if (typeof containerRef !== 'object' || containerRef === null || !('current' in containerRef)) {
console.error(
`CustomCursor: 'containerRef' must be a React ref object (created with useRef). Received: ${containerRef}`
);
}
}
// Validate centered
if (centered !== undefined && typeof centered !== 'boolean') {
console.error(
`CustomCursor: 'centered' must be a boolean. Received: ${centered} (${typeof centered})`
);
}
// Validate showDevIndicator
if (showDevIndicator !== undefined && typeof showDevIndicator !== 'boolean') {
console.error(
`CustomCursor: 'showDevIndicator' must be a boolean. Received: ${showDevIndicator} (${typeof showDevIndicator})`
);
}
// Validate callbacks
if (onMove !== undefined && typeof onMove !== 'function') {
console.error(
`CustomCursor: 'onMove' must be a function. Received: ${typeof onMove}`
);
}
if (onVisibilityChange !== undefined && typeof onVisibilityChange !== 'function') {
console.error(
`CustomCursor: 'onVisibilityChange' must be a function. Received: ${typeof onVisibilityChange}`
);
}
}