@mirawision/reactive-hooks
v1.1.0
Published
A comprehensive collection of 50+ React hooks for state management, UI interactions, device APIs, async operations, drag & drop, audio/speech, and more. Full TypeScript support with SSR safety.
Downloads
52
Keywords
Readme
@mirawision/reactive-hooks
A comprehensive collection of 50+ React hooks for state management, UI interactions, device APIs, async operations, drag & drop, audio/speech, and more. Built with full TypeScript support and SSR safety.
Installation
npm install @mirawision/reactive-hooksor
yarn add @mirawision/reactive-hooksUsage
Import all hooks
import { useToggle, useLocalStorage, useInput } from '@mirawision/reactive-hooks';Import individual hooks
import { useToggle } from '@mirawision/reactive-hooks/use-toggle';
import { useLocalStorage } from '@mirawision/reactive-hooks/use-local-storage';Quick Overview
The library is organized into 7 main categories:
- State Management (13 hooks): Toggle, lists, pagination, sorting, URL params, infinite scroll
- Storage & Persistence (3 hooks): Local storage, session storage, cookies
- UI & DOM Events (13 hooks): Event listeners, gestures, drag & drop, keyboard shortcuts
- Layout & Viewport (6 hooks): Window size, element size, scroll, media queries
- Device APIs & Browser State (8 hooks): Geolocation, orientation, speech, audio
- Async & Timing (10 hooks): Fetch, retry, polling, debounce, throttle, queues
- Lifecycle & Effects (3 hooks): Mount state, update effects
Hooks by Category
State Management
useToggle: Boolean state with toggle functionalityuseInput: Input field state with event handlinguseList: Array state with common operationsusePrevious: Access previous state valueuseCheckboxes: Manage collection of checkboxesuseSort: Manage sorting field and directionusePagination: Handle pagination with array slicinguseNumber: Numeric state with min/max limits and stepuseIterator: Iterate over arrays or numeric rangesuseQueryParams: URL query parameters as stateuseQueryParam: Single URL parameter as stateuseInfiniteScroll: Infinite loading with intersection observer
Storage & Persistence
useLocalStorage: localStorage state with syncuseSessionStorage: sessionStorage state with syncuseCookie: Cookie-based state management
UI & DOM Events
useEventListener: Safe DOM event subscriptionuseOnClickOutside: Handle clicks outside elementuseHover: Track element hover stateuseFocus: Track element focus stateuseKeyPress: Keyboard event handlinguseShortcuts: Keyboard shortcuts with modifiersuseLongPress: Long press detection for mouse/touchuseSwipe: Swipe gesture detectionuseDrag: Drag functionality with data transferuseDragEvents: Custom drag event handlersuseDropZone: File drop zone with filteringuseEventOnToggle: Conditional event listenersuseWindowScrollLock: Lock window scrolling for modals
Layout & Viewport
useWindowSize: Window dimensions with throttleuseElementSize: Element dimensions with ResizeObserveruseScroll: Scroll position trackinguseIntersectionObserver: Element visibility trackinguseMediaQuery: CSS media query matchinguseScreenSize: Responsive window dimensions
Device APIs & Browser State
useGeolocation: Device location trackinguseDeviceOrientation: Device orientation anglesuseOnlineStatus: Network connectivity stateusePageVisibility: Tab visibility trackinguseSpeechSynthesis: Text-to-speech functionalityuseSystemVoices: Available speech synthesis voicesuseSpeechRecognition: Speech-to-text functionalityuseAudio: HTML5 audio playback control
Async & Timing
useAsync: Async function state wrapperuseAsyncQueue: Sequential task executionuseRetry: Retry failed operationsusePolling: Periodic async executionuseFetch: Fetch wrapper with abort/cacheuseDebounce: Delay value/function updatesuseThrottle: Limit update frequencyuseTimeout: Delayed callback executionuseInterval: Repeated callback executionuseClock: Timer with controls
Lifecycle & Effects
useIsMounted: Component mount stateuseUpdateEffect: Skip first render effectuseFirstMountState: First render detection
Example Usage
State Management
// Toggle state
const [isOpen, toggle] = useToggle(false);
// List operations
const [items, { push, remove, move }] = useList(['a', 'b', 'c']);
// Checkbox collection
const { values, toggle, setAll, allChecked } = useCheckboxes({
item1: true,
item2: false
});
// Sorting management
const { field, dir, setField, toggleDir } = useSort('name', 'asc');
const sortedItems = items.sort((a, b) =>
dir === 'asc' ? a[field].localeCompare(b[field]) : b[field].localeCompare(a[field])
);
// Pagination
const { page, slice, next, prev } = usePagination(items.length, 10);
const pageItems = slice(items);
// Numeric state with limits
const { value, inc, dec } = useNumber(0, { min: 0, max: 100, step: 5 });
// Array/range iteration
const { value, next, hasNext } = useIterator(['a', 'b', 'c'], { loop: true });
const { value: index } = useIterator(5); // Iterates over 0..4Storage & Persistence
// Local storage with sync
const [value, { set, remove }] = useLocalStorage('key', 'default');
// Cookie management
const [token, setToken, removeToken] = useCookie('auth-token', '', {
days: 7,
secure: true
});Device APIs
// Geolocation tracking
const { coords, error } = useGeolocation({
enableHighAccuracy: true,
watch: true
});
// Device orientation
const { alpha, beta, gamma } = useDeviceOrientation();
// Tab visibility
const isVisible = usePageVisibility();
if (!isVisible) {
pauseVideoPlayback();
}
// Lock window scrolling for modal
function Modal({ isOpen }) {
useWindowScrollLock(isOpen);
return isOpen ? <div>Modal content</div> : null;
}
// Global keyboard shortcuts
useShortcuts([
{ combo: 'Ctrl+S', handler: (e) => saveDocument(e) },
{ combo: 'Ctrl+Shift+Z', handler: (e) => redo(e) },
{ combo: 'Meta+K', handler: (e) => openCommandPalette(e) }
]);
// URL query parameters as state
const [params, setParams] = useQueryParams();
const page = params.get('page') || '1';
setParams({ page: '2', sort: 'desc' });
// Single URL parameter
const [page, setPage] = useQueryParam('page');
setPage('3', { replace: true }); // Replace history state
// Infinite scroll
function List() {
const { ref, loading } = useInfiniteScroll({
hasMore: items.length < total,
loadMore: () => fetchNextPage(),
});
return (
<div>
{items.map(item => <Item key={item.id} {...item} />)}
<div ref={ref}>{loading ? 'Loading...' : null}</div>
</div>
);
}
// Long press detection
function Button() {
const handlers = useLongPress(() => console.log('long press!'), {
delay: 500,
cancelOnMove: true,
});
return <button {...handlers}>Press and hold</button>;
}
// Swipe gestures
function Card() {
const ref = useRef(null);
const { swiping, dir } = useSwipe(ref, {
minDistance: 50,
onSwipe: (dir, info) => console.log(dir, info),
});
return <div ref={ref} style={{ opacity: swiping ? 0.5 : 1 }} />;
}
// Drag and drop
function DraggableItem({ id, data }) {
const ref = useRef(null);
const { dragging } = useDrag(ref, { id, ...data });
return (
<div ref={ref} style={{ opacity: dragging ? 0.5 : 1 }}>
Draggable Item
</div>
);
}
function DropZone() {
const ref = useRef(null);
const { over } = useDropZone(ref, {
onDrop: (files) => console.log('Dropped files:', files),
multiple: true,
accept: 'image/*,.pdf'
});
return (
<div ref={ref} style={{ border: over ? '2px dashed blue' : '2px dashed gray' }}>
Drop files here
</div>
);
}
// Custom drag events
function CustomDragArea() {
const ref = useRef(null);
useDragEvents(ref, {
onDragStart: (e) => console.log('Drag started'),
onDrop: (e) => {
const data = e.dataTransfer.getData('application/json');
console.log('Dropped data:', JSON.parse(data));
}
});
return <div ref={ref}>Custom drag area</div>;
}
// Custom drag events
function CustomDragArea() {
const ref = useRef(null);
useDragEvents(ref, {
onDragStart: (e) => console.log('Drag started'),
onDrop: (e) => {
const data = e.dataTransfer.getData('application/json');
console.log('Dropped data:', JSON.parse(data));
}
});
return <div ref={ref}>Custom drag area</div>;
}
// Text-to-speech
function TextReader() {
const { speak, speaking, pause, resume } = useSpeechSynthesis();
const voices = useSystemVoices();
return (
<div>
<button onClick={() => speak('Hello world', { rate: 1.5 })}>
{speaking ? 'Speaking...' : 'Speak'}
</button>
<select>{voices.map(v => <option key={v.name}>{v.name}</option>)}</select>
</div>
);
}
// Speech recognition
function VoiceInput() {
const { transcript, listening, start, stop } = useSpeechRecognition({
continuous: true,
interimResults: true,
});
return (
<div>
<button onClick={listening ? stop : start}>
{listening ? 'Stop' : 'Start'} listening
</button>
<p>{transcript}</p>
</div>
);
}
// Audio player
function AudioPlayer() {
const { audioRef, playing, play, pause, currentTime, duration, volume, setVolume } = useAudio('/audio.mp3');
return (
<div>
<audio ref={audioRef} />
<button onClick={playing ? pause : play}>
{playing ? 'Pause' : 'Play'}
</button>
<input
type="range"
min="0"
max={duration}
value={currentTime}
onChange={(e) => seek(Number(e.target.value))}
/>
<input
type="range"
min="0"
max="1"
step="0.1"
value={volume}
onChange={(e) => setVolume(Number(e.target.value))}
/>
<span>{Math.floor(currentTime)}s / {Math.floor(duration)}s</span>
</div>
);
}Async Operations
// Sequential task queue
const queue = useAsyncQueue();
await queue.enqueue(() => saveData());
// Retry with backoff
const { run, error } = useRetry(fetchData, {
retries: 3,
delayMs: 1000
});
// Debounced search
const debouncedQuery = useDebounce(searchQuery, 300);Features
- 50+ Hooks: Comprehensive coverage of React development needs
- Type-safe: Full TypeScript support with detailed type definitions
- Tree-shakeable: Import only what you need, reduce bundle size
- Well-tested: Extensive test coverage for all hooks
- SSR-safe: Server-side rendering support with graceful degradation
- Lightweight: Minimal dependencies, optimized for performance
- React 16.8+ compatible: Modern hooks API with backward compatibility (supports React 19)
- Cross-platform: Works across browsers, devices, and platforms
- Accessibility: Built with accessibility best practices in mind
- Performance: Optimized for performance with proper cleanup and memoization
Library Statistics
- Total Hooks: 56 hooks across 7 categories
- TypeScript Coverage: 100% with full type definitions
- Test Coverage: Comprehensive tests for all hooks
- Bundle Size: Tree-shakeable, import only what you need
- Browser Support: Modern browsers with SSR safety
- React Versions: 16.8+ (hooks support, including React 19)
API Reference
Each hook is documented with TypeScript types and JSDoc comments. For detailed API documentation:
- See the TypeScript definitions
- Check individual hook files
- Refer to test files for usage examples
Contributing
Contributions are welcome! Please read our contributing guidelines for details.
