@mohasinac/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,366 @@
1
+ import { RefObject } from 'react';
2
+
3
+ /**
4
+ * useMediaQuery Hook
5
+ *
6
+ * Detects if a CSS media query matches the current viewport.
7
+ * Returns true/false based on whether the query matches.
8
+ *
9
+ * @param query - CSS media query string (e.g., '(min-width: 768px)')
10
+ * @returns boolean - Whether the media query currently matches
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const isMobile = useMediaQuery('(max-width: 767px)');
15
+ * const isDesktop = useMediaQuery('(min-width: 1024px)');
16
+ * ```
17
+ */
18
+ declare function useMediaQuery(query: string): boolean;
19
+
20
+ /**
21
+ * useBreakpoint Hook
22
+ *
23
+ * Convenience hook for detecting common Tailwind breakpoints.
24
+ * Returns boolean flags and the current breakpoint name.
25
+ *
26
+ * Breakpoints (Tailwind defaults):
27
+ * - Mobile: < 768px
28
+ * - Tablet: 768px - 1023px
29
+ * - Desktop: >= 1024px
30
+ *
31
+ * @returns Object with breakpoint detection flags
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * const { isMobile, isTablet, isDesktop, breakpoint } = useBreakpoint();
36
+ *
37
+ * if (isMobile) {
38
+ * return <MobileView />;
39
+ * }
40
+ * return <DesktopView />;
41
+ * ```
42
+ */
43
+ declare function useBreakpoint(): {
44
+ isMobile: boolean;
45
+ isTablet: boolean;
46
+ isDesktop: boolean;
47
+ breakpoint: "mobile" | "tablet" | "desktop";
48
+ };
49
+
50
+ /**
51
+ * Configuration options for useClickOutside hook
52
+ */
53
+ interface UseClickOutsideOptions {
54
+ /** Whether the hook is enabled */
55
+ enabled?: boolean;
56
+ /** Event type to listen for (default: 'mousedown') */
57
+ eventType?: "mousedown" | "mouseup" | "click";
58
+ /** Refs to additional elements that should be considered "inside" */
59
+ additionalRefs?: RefObject<HTMLElement | null>[];
60
+ }
61
+ /**
62
+ * useClickOutside Hook
63
+ *
64
+ * Detects clicks outside of specified element(s) and triggers a callback.
65
+ * Commonly used for dropdowns, modals, and popovers.
66
+ *
67
+ * @param ref - Primary element reference
68
+ * @param callback - Function to call when clicking outside
69
+ * @param options - Configuration options
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * const dropdownRef = useRef<HTMLDivElement>(null);
74
+ * const triggerRef = useRef<HTMLButtonElement>(null);
75
+ *
76
+ * useClickOutside(dropdownRef, () => {
77
+ * setIsOpen(false);
78
+ * }, {
79
+ * additionalRefs: [triggerRef],
80
+ * enabled: isOpen,
81
+ * });
82
+ * ```
83
+ */
84
+ declare function useClickOutside<T extends HTMLElement = HTMLElement>(ref: RefObject<T | null>, callback: (event: MouseEvent | TouchEvent) => void, options?: UseClickOutsideOptions): void;
85
+
86
+ /**
87
+ * Key combination modifiers
88
+ */
89
+ interface KeyModifiers {
90
+ ctrl?: boolean;
91
+ shift?: boolean;
92
+ alt?: boolean;
93
+ meta?: boolean;
94
+ }
95
+ /**
96
+ * Configuration options for useKeyPress hook
97
+ */
98
+ interface UseKeyPressOptions extends KeyModifiers {
99
+ /** Whether the hook is enabled */
100
+ enabled?: boolean;
101
+ /** Event type to listen for (default: 'keydown') */
102
+ eventType?: "keydown" | "keyup" | "keypress";
103
+ /** Prevent default behavior */
104
+ preventDefault?: boolean;
105
+ /** Target element (default: document) */
106
+ target?: HTMLElement | Document | Window;
107
+ }
108
+ /**
109
+ * useKeyPress Hook
110
+ *
111
+ * Detects keyboard events with support for key combinations.
112
+ * Useful for keyboard shortcuts and accessibility.
113
+ *
114
+ * @param key - Key or array of keys to listen for (e.g., 'Enter', 'Escape', ['a', 'A'])
115
+ * @param callback - Function to call when key is pressed
116
+ * @param options - Configuration options including modifiers
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * // Simple key press
121
+ * useKeyPress('Escape', () => closeModal());
122
+ *
123
+ * // Key combination (Ctrl+S)
124
+ * useKeyPress('s', handleSave, {
125
+ * ctrl: true,
126
+ * preventDefault: true,
127
+ * });
128
+ *
129
+ * // Multiple keys
130
+ * useKeyPress(['Enter', 'NumpadEnter'], handleSubmit);
131
+ * ```
132
+ */
133
+ declare function useKeyPress(key: string | string[], callback: (event: KeyboardEvent) => void, options?: UseKeyPressOptions): void;
134
+
135
+ /**
136
+ * useLongPress Hook
137
+ *
138
+ * Fires `callback` after the element is held for `ms` milliseconds.
139
+ * A quick tap (pointer-up before the threshold) does NOT fire the callback.
140
+ * Safe to use on both mouse and touch devices.
141
+ *
142
+ * @param callback - Function to call on long-press
143
+ * @param ms - Hold duration in ms before callback fires (default: 500)
144
+ *
145
+ * @example
146
+ * ```tsx
147
+ * const longPress = useLongPress(() => openContextMenu(), 500);
148
+ *
149
+ * return (
150
+ * <tr {...longPress}>…</tr>
151
+ * );
152
+ * ```
153
+ */
154
+ declare function useLongPress(callback: () => void, ms?: number): {
155
+ onMouseDown: () => void;
156
+ onMouseUp: () => void;
157
+ onMouseLeave: () => void;
158
+ onTouchStart: () => void;
159
+ onTouchEnd: () => void;
160
+ };
161
+
162
+ /**
163
+ * Gesture types supported
164
+ */
165
+ type GestureType = "tap" | "doubletap" | "pinch" | "rotate";
166
+ /**
167
+ * Configuration options for useGesture hook
168
+ */
169
+ interface UseGestureOptions {
170
+ /** Callback for tap gesture */
171
+ onTap?: (x: number, y: number) => void;
172
+ /** Callback for double tap gesture */
173
+ onDoubleTap?: (x: number, y: number) => void;
174
+ /** Callback for pinch gesture (zoom in/out) */
175
+ onPinch?: (scale: number, distance: number) => void;
176
+ /** Callback during pinching */
177
+ onPinching?: (scale: number) => void;
178
+ /** Callback for rotation gesture */
179
+ onRotate?: (angle: number) => void;
180
+ /** Callback during rotation */
181
+ onRotating?: (angle: number) => void;
182
+ /** Maximum time between taps for double tap (ms, default: 300) */
183
+ doubleTapDelay?: number;
184
+ /** Maximum movement allowed for tap (px, default: 10) */
185
+ tapMovementThreshold?: number;
186
+ /** Prevent default behavior */
187
+ preventDefault?: boolean;
188
+ }
189
+ /**
190
+ * useGesture Hook
191
+ *
192
+ * Detects various touch gestures including tap, double tap, pinch, and rotate.
193
+ * Primarily designed for touch devices but also works with mouse for basic gestures.
194
+ *
195
+ * @param ref - Reference to the element to attach gesture handlers
196
+ * @param options - Configuration options for gesture detection
197
+ *
198
+ * @example
199
+ * ```tsx
200
+ * const ref = useRef<HTMLDivElement>(null);
201
+ *
202
+ * useGesture(ref, {
203
+ * onTap: (x, y) => console.log('Tapped at', x, y),
204
+ * onDoubleTap: () => console.log('Double tapped'),
205
+ * onPinch: (scale) => console.log('Pinch scale', scale),
206
+ * });
207
+ *
208
+ * return <div ref={ref}>Touch me!</div>;
209
+ * ```
210
+ */
211
+ declare function useGesture<T extends HTMLElement = HTMLElement>(ref: RefObject<T | null>, options?: UseGestureOptions): void;
212
+
213
+ /**
214
+ * Swipe direction types
215
+ */
216
+ type SwipeDirection = "left" | "right" | "up" | "down";
217
+ /**
218
+ * Configuration options for useSwipe hook
219
+ */
220
+ interface UseSwipeOptions {
221
+ /** Minimum distance in pixels to register as a swipe (default: 50) */
222
+ minSwipeDistance?: number;
223
+ /** Maximum time in ms for a swipe gesture (default: 300) */
224
+ maxSwipeTime?: number;
225
+ /** Threshold for swipe velocity (pixels/ms, default: 0.3) */
226
+ velocityThreshold?: number;
227
+ /** Callback when swipe is detected */
228
+ onSwipe?: (direction: SwipeDirection, distance: number, velocity: number) => void;
229
+ /** Callback for specific directions */
230
+ onSwipeLeft?: (distance: number, velocity: number) => void;
231
+ onSwipeRight?: (distance: number, velocity: number) => void;
232
+ onSwipeUp?: (distance: number, velocity: number) => void;
233
+ onSwipeDown?: (distance: number, velocity: number) => void;
234
+ /** Callback during swipe (for dragging effect) */
235
+ onSwiping?: (deltaX: number, deltaY: number) => void;
236
+ /** Callback when swipe starts */
237
+ onSwipeStart?: () => void;
238
+ /** Callback when swipe ends (regardless of direction detected) */
239
+ onSwipeEnd?: () => void;
240
+ /** Prevent default behavior during touch */
241
+ preventDefault?: boolean;
242
+ }
243
+ /**
244
+ * useSwipe Hook
245
+ *
246
+ * Detects swipe gestures on touch and mouse events.
247
+ * Works on both mobile (touch) and desktop (mouse drag).
248
+ *
249
+ * @param ref - Reference to the element to attach swipe handlers
250
+ * @param options - Configuration options for swipe detection
251
+ *
252
+ * @example
253
+ * ```tsx
254
+ * const ref = useRef<HTMLDivElement>(null);
255
+ *
256
+ * useSwipe(ref, {
257
+ * onSwipeLeft: () => console.log('Swiped left'),
258
+ * onSwipeRight: () => console.log('Swiped right'),
259
+ * minSwipeDistance: 100,
260
+ * });
261
+ *
262
+ * return <div ref={ref}>Swipe me!</div>;
263
+ * ```
264
+ */
265
+ declare function useSwipe<T extends HTMLElement = HTMLElement>(ref: RefObject<T | null>, options?: UseSwipeOptions): void;
266
+
267
+ interface UsePullToRefreshOptions {
268
+ /** Distance in px the user must pull before onRefresh triggers (default: 80) */
269
+ threshold?: number;
270
+ }
271
+ interface UsePullToRefreshReturn {
272
+ /** Attach to the scrollable container element */
273
+ containerRef: RefObject<HTMLDivElement | null>;
274
+ /** `true` while the user is actively pulling */
275
+ isPulling: boolean;
276
+ /** Pull progress from 0 (not started) to 1 (threshold reached) */
277
+ progress: number;
278
+ }
279
+ /**
280
+ * usePullToRefresh Hook
281
+ *
282
+ * Attaches touch event listeners to `containerRef`.
283
+ * When the user overscrolls from the very top and pulls down past `threshold`,
284
+ * `onRefresh` is called. Progress (0–1) can be used to render a loading indicator.
285
+ *
286
+ * @param onRefresh - Async function called when pull threshold is reached
287
+ * @param options - Configuration: `threshold` in px (default 80)
288
+ *
289
+ * @example
290
+ * ```tsx
291
+ * const { containerRef, isPulling, progress } = usePullToRefresh(async () => {
292
+ * await refetchOrders();
293
+ * });
294
+ *
295
+ * return (
296
+ * <div ref={containerRef} className="overflow-y-auto">
297
+ * {isPulling && <PullIndicator progress={progress} />}
298
+ * {…}
299
+ * </div>
300
+ * );
301
+ * ```
302
+ */
303
+ declare function usePullToRefresh(onRefresh: () => Promise<void>, options?: UsePullToRefreshOptions): UsePullToRefreshReturn;
304
+
305
+ /**
306
+ * useCountdown — tracks time remaining until a future date.
307
+ *
308
+ * Returns `null` when the target date has passed or is not provided.
309
+ *
310
+ * Supports:
311
+ * - `Date` objects
312
+ * - ISO strings / numeric timestamps
313
+ * - Firestore Timestamp JSON shape `{ _seconds, _nanoseconds }` (serialised
314
+ * by Firestore's REST API — no Firestore SDK import needed)
315
+ */
316
+ interface CountdownRemaining {
317
+ days: number;
318
+ hours: number;
319
+ minutes: number;
320
+ seconds: number;
321
+ }
322
+ /**
323
+ * @example
324
+ * ```tsx
325
+ * const remaining = useCountdown(auction.endsAt);
326
+ * if (!remaining) return <span>Ended</span>;
327
+ * return <span>{remaining.hours}h {remaining.minutes}m {remaining.seconds}s</span>;
328
+ * ```
329
+ */
330
+ declare function useCountdown(endDate: Date | string | undefined): CountdownRemaining | null;
331
+
332
+ interface UseCameraOptions {
333
+ facingMode?: "user" | "environment";
334
+ video?: boolean | MediaTrackConstraints;
335
+ audio?: boolean;
336
+ }
337
+ interface UseCameraReturn {
338
+ isSupported: boolean;
339
+ isActive: boolean;
340
+ isCapturing: boolean;
341
+ stream: MediaStream | null;
342
+ error: string | null;
343
+ videoRef: React.RefObject<HTMLVideoElement | null>;
344
+ startCamera: (options?: UseCameraOptions) => Promise<void>;
345
+ stopCamera: () => void;
346
+ takePhoto: () => Blob | null;
347
+ startRecording: () => void;
348
+ stopRecording: () => Promise<Blob>;
349
+ switchCamera: () => Promise<void>;
350
+ }
351
+ /**
352
+ * useCamera
353
+ *
354
+ * Provides access to the device camera via the MediaDevices API.
355
+ * Zero domain imports. Safe to use in any Tier 1 / Tier 2 component.
356
+ *
357
+ * Lifecycle:
358
+ * - Call `startCamera()` to open the stream and wire `videoRef` to a <video> element.
359
+ * - `stopCamera()` releases hardware tracks (turns off the camera indicator light).
360
+ * - `takePhoto()` captures the current frame as image/webp.
361
+ * - `startRecording()` / `stopRecording()` use MediaRecorder (video/webm output).
362
+ * - `useEffect` cleanup calls `stopCamera()` automatically on unmount.
363
+ */
364
+ declare function useCamera(): UseCameraReturn;
365
+
366
+ export { type CountdownRemaining, type GestureType, type KeyModifiers, type SwipeDirection, type UseCameraOptions, type UseCameraReturn, type UseClickOutsideOptions, type UseGestureOptions, type UseKeyPressOptions, type UsePullToRefreshOptions, type UsePullToRefreshReturn, type UseSwipeOptions, useBreakpoint, useCamera, useClickOutside, useCountdown, useGesture, useKeyPress, useLongPress, useMediaQuery, usePullToRefresh, useSwipe };