clicknhold
Version:
React hook for handling click and hold events
257 lines (201 loc) • 5.8 kB
Markdown
# clicknhold
React hook for handling long press events with progress tracking. Supports mouse, touch, and keyboard events.
## Installation
```bash
# NPM
npm install clicknhold
# Yarn
yarn add clicknhold
# PNPM
pnpm add clicknhold
```
### CDN
```html
<script src="https://cdn.jsdelivr.net/npm/clicknhold@latest/dist/index.min.js"></script>
```
або
```html
<script src="https://unpkg.com/clicknhold@latest/dist/index.min.js"></script>
```
## Basic Usage
```jsx
// Using hook directly
import { useClicknHold } from 'clicknhold';
function App() {
const { isHolding, handlers } = useClicknHold({
duration: 2000,
onComplete: () => console.log('Completed!'),
onProgress: (progress) => console.log(`Progress: ${progress}`),
});
return (
<button {...handlers}>
{isHolding ? 'Holding...' : 'Click and hold!'}
</button>
);
}
// Using pre-built components
import { DeleteHold, ConfirmHold, LoadHold } from 'clicknhold';
function App() {
return (
<div>
<DeleteHold onDelete={() => console.log('Deleted!')} />
<ConfirmHold onConfirm={() => console.log('Confirmed!')} />
<LoadHold onLoad={() => console.log('Loaded!')} />
</div>
);
}
```
## Pre-built Components
### Default Durations
- `DeleteHold`: 2000ms
- `ConfirmHold`: 1500ms
- `LoadHold`: 2500ms
### Styling with Tailwind CSS
```jsx
// Basic styling
<DeleteHold
onDelete={() => alert('Deleted!')}
className="rounded-lg shadow-lg hover:shadow-xl"
/>
// Custom colors and effects
<ConfirmHold
onConfirm={() => alert('Confirmed!')}
className="bg-blue-600 hover:bg-blue-700 rounded-full px-8
transition-all duration-300 hover:scale-105"
/>
// Progress bar styling
<LoadHold
onLoad={() => alert('Loaded!')}
className="bg-purple-600 rounded-md [&>div]:bg-white/40 [&>div]:h-1"
/>
// Complex example
<div className="flex gap-4 p-4">
<DeleteHold
onDelete={() => alert('Deleted!')}
className="bg-red-600 hover:bg-red-700 rounded-lg shadow-md
transition-all duration-300 hover:shadow-lg
[&>div]:bg-white/30 [&>div]:h-1"
/>
<ConfirmHold
onConfirm={() => alert('Confirmed!')}
className="bg-blue-600 hover:bg-blue-700 rounded-full px-8
shadow-md hover:shadow-xl transition-all duration-300"
/>
<LoadHold
onLoad={() => alert('Loaded!')}
className="bg-purple-600 hover:bg-purple-700 rounded-md
border-2 border-white/20 hover:scale-105 transition-transform"
/>
</div>
```
## API
### useClicknHold Options
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| duration | number | 2000 | Hold duration in milliseconds |
| onComplete | () => void | undefined | Callback triggered when hold completes |
| onStart | () => void | undefined | Callback triggered when hold starts |
| onCancel | () => void | undefined | Callback triggered when hold is cancelled |
| onProgress | (progress: number) => void | undefined | Callback for tracking progress (0-1) |
| disabled | boolean | false | Disable functionality |
### Component Props
All components (`DeleteHold`, `ConfirmHold`, `LoadHold`) accept:
| Prop | Type | Description |
|------|------|-------------|
| className | string | CSS classes (supports Tailwind) |
| style | CSSProperties | Inline styles |
| onDelete/onConfirm/onLoad | () => void | Callback on successful hold |
### Return Values
| Value | Type | Description |
|-------|------|-------------|
| isHolding | boolean | Hold state |
| handlers | object | Event handler object |
| startHolding | function | Function to programmatically start holding |
| stopHolding | function | Function to programmatically stop holding |
## Usage Examples
### Progress Bar
```jsx
function ProgressButton() {
const [progress, setProgress] = useState(0);
const { isHolding, handlers } = useClicknHold({
duration: 3000,
onProgress: setProgress,
onComplete: () => alert('Done!'),
});
return (
<button {...handlers} style={{ position: 'relative' }}>
<div
style={{
position: 'absolute',
bottom: 0,
left: 0,
height: '4px',
width: `${progress * 100}%`,
backgroundColor: 'blue',
transition: 'width 0.1s linear',
}}
/>
{isHolding ? `${Math.round(progress * 100)}%` : 'Hold to load'}
</button>
);
}
```
### With Disabled State
```jsx
function DisableableButton() {
const [isDisabled, setIsDisabled] = useState(false);
const { isHolding, handlers } = useClicknHold({
duration: 2000,
disabled: isDisabled,
onComplete: () => console.log('Completed!'),
});
return (
<div>
<button {...handlers}>
{isHolding ? 'Holding...' : 'Click and hold'}
</button>
<label>
<input
type="checkbox"
checked={isDisabled}
onChange={(e) => setIsDisabled(e.target.checked)}
/>
Disable functionality
</label>
</div>
);
}
```
### Programmatic Control
```jsx
function ProgrammaticControl() {
const { isHolding, startHolding, stopHolding } = useClicknHold({
duration: 2000,
onComplete: () => console.log('Completed!'),
});
return (
<div>
<button onClick={() => startHolding()}>Start</button>
<button onClick={() => stopHolding()}>Stop</button>
<div>Status: {isHolding ? 'Active' : 'Inactive'}</div>
</div>
);
}
```
## Features
- Mouse event support
- Touch screen support
- Keyboard support (Enter and Space)
- Progress tracking
- TypeScript support
- Tailwind CSS support
- No external dependencies
- Lightweight (~2KB gzipped)
## Browser Support
- Chrome ✓
- Firefox ✓
- Safari ✓
- Edge ✓
- IE 11 ✗
## License
MIT © [dolhocodev](https://github.com/dolhocodev)