@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.
267 lines (205 loc) ⢠8.07 kB
Markdown
# React Component Cursor
[](https://www.npmjs.com/package/@yhattav/react-component-cursor)
[](https://www.npmjs.com/package/@yhattav/react-component-cursor)
[](https://bundlephobia.com/package/@yhattav/react-component-cursor)
[](https://www.typescriptlang.org/)
[](https://github.com/yhattav/react-component-cursor/blob/main/LICENSE)
[](https://yhattav.github.io/react-component-cursor/)
[](https://github.com/yhattav/react-component-cursor)
A flexible and customizable React component for creating smooth, interactive custom cursors and enhancements.
## Features
- Use any React component
- Smooth cursor movement with configurable smoothing
- Global and Container-specific cursors
- Supports Multiple instances
- Lightweight (<10KB)
- Zero dependencies (except React)
## Installation
```bash
npm install @yhattav/react-component-cursor
or
yarn add @yhattav/react-component-cursor
```
**Note:** If you wish to, You'll need to hide the native cursor with CSS (like `cursor: none` in the example above). See our [styling guide](docs/CURSOR_STYLING.md) for different approaches.
š **New to the library?** Check out our comprehensive [Getting Started Guide](GETTING_STARTED.md) for step-by-step tutorials and examples.
## Basic Usage
```tsx
import { CustomCursor } from '@yhattav/react-component-cursor';
function App() {
return (
<>
{/* Hide native cursor globally */}
<style>{`body { cursor: none !important; }`}</style>
<CustomCursor>
<div
style={{
width: '20px',
height: '20px',
backgroundColor: '#3b82f6',
borderRadius: '50%',
}}
/>
</CustomCursor>
{/* Your app content */}
</>
);
}
```
## š Complete API Reference
### `<CustomCursor>` Component
The main component for creating custom cursors.
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `ReactNode` | - | The React component/element to use as cursor content |
| `enabled` | `boolean` | `true` | Whether the cursor is enabled and visible |
| `smoothness` | `number` | `1` | Movement smoothing factor (1=instant, higher=smoother) |
| `containerRef` | `RefObject<HTMLElement>` | - | Limit cursor to specific container element |
| `offset` | `CursorOffset` | `{ x: 0, y: 0 }` | Pixel offset from mouse position |
| `centered` | `boolean` | `true` | Auto-center cursor content on mouse position |
| `throttleMs` | `number` | `0` | Throttle mouse events in milliseconds |
| `className` | `string` | `''` | Additional CSS classes for cursor container |
| `style` | `CSSProperties` | `{}` | Additional inline styles for cursor container |
| `zIndex` | `number` | `9999` | CSS z-index for cursor container |
| `onMove` | `CursorMoveHandler` | - | Callback fired on cursor movement |
| `onVisibilityChange` | `CursorVisibilityHandler` | - | Callback fired when cursor visibility changes |
| `id` | `string` | auto-generated | Unique identifier for cursor instance |
| `showDevIndicator` | `boolean` | `true` | **[Dev Only]** Show debug ring in development |
| `data-testid` | `string` | - | Test ID for automated testing |
| `role` | `string` | - | ARIA role for accessibility |
| `aria-label` | `string` | - | ARIA label for accessibility |
### š¦ TypeScript Types
The library is written in TypeScript and includes built-in type definitions.
```tsx
import type {
CustomCursorProps,
CursorPosition,
CursorOffset,
CursorMoveHandler,
CursorVisibilityHandler,
CursorVisibilityReason,
} from '@yhattav/react-component-cursor';
```
**š [Complete TypeScript Reference ā](docs/TYPES.md)**
All prop types, interfaces, and future-ready types with usage examples.
### š§ SSR Utilities
Optional utility functions for advanced SSR scenarios:
```tsx
import { isSSR, isBrowser, browserOnly, safeDocument, safeWindow } from '@yhattav/react-component-cursor';
```
**š [Complete SSR Guide ā](docs/SSR.md)**
### ā” Performance
Optimized for performance with advanced control for complex use cases.
**š [Complete Performance Guide ā](docs/PERFORMANCE.md)**
Optimization strategies, settings matrix, and advanced techniques.
### š Server-Side Rendering (SSR)
Works out of the box with Next.js, Gatsby, Remix, and other SSR frameworks.
```tsx
// Zero configuration needed - SSR handled automatically
import { CustomCursor } from '@yhattav/react-component-cursor';
<CustomCursor>
<div className="cursor">āØ</div>
</CustomCursor>
```
**š [Complete SSR Guide ā](docs/SSR.md)**
### š® Examples & Demos
**Live Demo**: [Interactive Examples & Showcase ā](https://yhattav.github.io/react-component-cursor/)
**Local Examples** (clone and run):
```bash
# Vite React example with multiple cursor demos
cd example && npm install && npm run dev
# Next.js example with SSR and advanced patterns
cd example-nextjs && npm install && npm run dev
```
### š Usage Guidelines
#### Framework Compatibility
- ā
**Next.js** - Full SSR support with zero configuration
- ā
**Gatsby** - Static generation compatible
- ā
**Remix** - Server-side rendering works out of the box
- ā
**Vite/CRA** - Client-side rendering with optimal performance
- ā
**Astro** - Partial hydration compatible
## Advanced Usage
### Container-Specific Cursor
```tsx
function ContainerExample() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div
ref={containerRef}
style={{
position: 'relative',
cursor: 'none', // Hide native cursor in this container
}}
>
<CustomCursor containerRef={containerRef} smoothness={2}>
<div
style={{
width: '40px',
height: '40px',
border: '2px solid #ef4444',
borderRadius: '50%',
}}
/>
</CustomCursor>
{/* Container content */}
</div>
);
}
```
### Interactive Cursor
```tsx
function InteractiveCursor() {
const [isHovered, setIsHovered] = useState(false);
return (
<>
<style>{`body { cursor: none; }`}</style>
<div>
<CustomCursor>
<div
style={{
width: isHovered ? '60px' : '20px',
height: isHovered ? '60px' : '20px',
backgroundColor: '#3b82f6',
borderRadius: '50%',
transition: 'all 0.2s ease',
}}
/>
</CustomCursor>
<button
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
Hover me!
</button>
</div>
</>
);
}
```
### Visibility Change Handler
```tsx
function VisibilityAwareCursor() {
const handleVisibilityChange = (isVisible: boolean, reason: string) => {
console.log('Cursor visibility:', isVisible, 'reason:', reason);
// Reason can be: 'container', 'disabled', or other values in future versions
};
return (
<CustomCursor onVisibilityChange={handleVisibilityChange}>
<div
style={{
width: '20px',
height: '20px',
backgroundColor: '#3b82f6',
borderRadius: '50%',
}}
/>
</CustomCursor>
);
}
```
## Contributing
We welcome contributions! See our guides:
- **[Contributing Guide](CONTRIBUTING.md)** - How to contribute
- **[Development Guide](DEVELOPMENT.md)** - Complete development setup and workflow
## License
MIT Ā© [Yonatan Hattav](https://github.com/yhattav)