@usefy/use-click-any-where 0.0.10 → 0.0.12
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.
- package/README.md +57 -62
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ This package requires React 18 or 19:
|
|
|
83
83
|
## Quick Start
|
|
84
84
|
|
|
85
85
|
```tsx
|
|
86
|
-
import { useClickAnyWhere } from
|
|
86
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
87
87
|
|
|
88
88
|
function ClickTracker() {
|
|
89
89
|
const [lastClick, setLastClick] = useState({ x: 0, y: 0 });
|
|
@@ -110,18 +110,18 @@ A hook that listens for document-wide click events.
|
|
|
110
110
|
|
|
111
111
|
#### Parameters
|
|
112
112
|
|
|
113
|
-
| Parameter | Type
|
|
114
|
-
|
|
113
|
+
| Parameter | Type | Description |
|
|
114
|
+
| --------- | ----------------------------- | ------------------------------------------------ |
|
|
115
115
|
| `handler` | `(event: MouseEvent) => void` | Callback function called on every document click |
|
|
116
|
-
| `options` | `UseClickAnyWhereOptions`
|
|
116
|
+
| `options` | `UseClickAnyWhereOptions` | Configuration options |
|
|
117
117
|
|
|
118
118
|
#### Options
|
|
119
119
|
|
|
120
|
-
| Option
|
|
121
|
-
|
|
122
|
-
| `enabled` | `boolean` | `true`
|
|
123
|
-
| `capture` | `boolean` | `false` | Use event capture phase instead of bubble
|
|
124
|
-
| `passive` | `boolean` | `true`
|
|
120
|
+
| Option | Type | Default | Description |
|
|
121
|
+
| --------- | --------- | ------- | ------------------------------------------ |
|
|
122
|
+
| `enabled` | `boolean` | `true` | Whether the event listener is active |
|
|
123
|
+
| `capture` | `boolean` | `false` | Use event capture phase instead of bubble |
|
|
124
|
+
| `passive` | `boolean` | `true` | Use passive event listener for performance |
|
|
125
125
|
|
|
126
126
|
#### Returns
|
|
127
127
|
|
|
@@ -134,8 +134,8 @@ A hook that listens for document-wide click events.
|
|
|
134
134
|
### Close Dropdown on Outside Click
|
|
135
135
|
|
|
136
136
|
```tsx
|
|
137
|
-
import { useClickAnyWhere } from
|
|
138
|
-
import { useRef, useState } from
|
|
137
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
138
|
+
import { useRef, useState } from "react";
|
|
139
139
|
|
|
140
140
|
function Dropdown() {
|
|
141
141
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -144,7 +144,10 @@ function Dropdown() {
|
|
|
144
144
|
useClickAnyWhere(
|
|
145
145
|
(event) => {
|
|
146
146
|
// Close if clicked outside the dropdown
|
|
147
|
-
if (
|
|
147
|
+
if (
|
|
148
|
+
dropdownRef.current &&
|
|
149
|
+
!dropdownRef.current.contains(event.target as Node)
|
|
150
|
+
) {
|
|
148
151
|
setIsOpen(false);
|
|
149
152
|
}
|
|
150
153
|
},
|
|
@@ -153,9 +156,7 @@ function Dropdown() {
|
|
|
153
156
|
|
|
154
157
|
return (
|
|
155
158
|
<div ref={dropdownRef}>
|
|
156
|
-
<button onClick={() => setIsOpen(!isOpen)}>
|
|
157
|
-
Toggle Menu
|
|
158
|
-
</button>
|
|
159
|
+
<button onClick={() => setIsOpen(!isOpen)}>Toggle Menu</button>
|
|
159
160
|
{isOpen && (
|
|
160
161
|
<ul className="dropdown-menu">
|
|
161
162
|
<li>Option 1</li>
|
|
@@ -171,15 +172,18 @@ function Dropdown() {
|
|
|
171
172
|
### Modal with Click Outside to Close
|
|
172
173
|
|
|
173
174
|
```tsx
|
|
174
|
-
import { useClickAnyWhere } from
|
|
175
|
-
import { useRef } from
|
|
175
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
176
|
+
import { useRef } from "react";
|
|
176
177
|
|
|
177
178
|
function Modal({ isOpen, onClose, children }: ModalProps) {
|
|
178
179
|
const modalRef = useRef<HTMLDivElement>(null);
|
|
179
180
|
|
|
180
181
|
useClickAnyWhere(
|
|
181
182
|
(event) => {
|
|
182
|
-
if (
|
|
183
|
+
if (
|
|
184
|
+
modalRef.current &&
|
|
185
|
+
!modalRef.current.contains(event.target as Node)
|
|
186
|
+
) {
|
|
183
187
|
onClose();
|
|
184
188
|
}
|
|
185
189
|
},
|
|
@@ -201,17 +205,14 @@ function Modal({ isOpen, onClose, children }: ModalProps) {
|
|
|
201
205
|
### Context Menu
|
|
202
206
|
|
|
203
207
|
```tsx
|
|
204
|
-
import { useClickAnyWhere } from
|
|
205
|
-
import { useState } from
|
|
208
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
209
|
+
import { useState } from "react";
|
|
206
210
|
|
|
207
211
|
function ContextMenu() {
|
|
208
212
|
const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);
|
|
209
213
|
|
|
210
214
|
// Close menu on any click
|
|
211
|
-
useClickAnyWhere(
|
|
212
|
-
() => setMenu(null),
|
|
213
|
-
{ enabled: menu !== null }
|
|
214
|
-
);
|
|
215
|
+
useClickAnyWhere(() => setMenu(null), { enabled: menu !== null });
|
|
215
216
|
|
|
216
217
|
const handleContextMenu = (e: React.MouseEvent) => {
|
|
217
218
|
e.preventDefault();
|
|
@@ -224,7 +225,7 @@ function ContextMenu() {
|
|
|
224
225
|
{menu && (
|
|
225
226
|
<div
|
|
226
227
|
className="context-menu"
|
|
227
|
-
style={{ position:
|
|
228
|
+
style={{ position: "fixed", left: menu.x, top: menu.y }}
|
|
228
229
|
>
|
|
229
230
|
<button>Cut</button>
|
|
230
231
|
<button>Copy</button>
|
|
@@ -239,11 +240,13 @@ function ContextMenu() {
|
|
|
239
240
|
### Click Coordinate Logger
|
|
240
241
|
|
|
241
242
|
```tsx
|
|
242
|
-
import { useClickAnyWhere } from
|
|
243
|
-
import { useState } from
|
|
243
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
244
|
+
import { useState } from "react";
|
|
244
245
|
|
|
245
246
|
function ClickLogger() {
|
|
246
|
-
const [clicks, setClicks] = useState<
|
|
247
|
+
const [clicks, setClicks] = useState<
|
|
248
|
+
Array<{ x: number; y: number; time: Date }>
|
|
249
|
+
>([]);
|
|
247
250
|
|
|
248
251
|
useClickAnyWhere((event) => {
|
|
249
252
|
setClicks((prev) => [
|
|
@@ -270,13 +273,13 @@ function ClickLogger() {
|
|
|
270
273
|
### With Capture Phase
|
|
271
274
|
|
|
272
275
|
```tsx
|
|
273
|
-
import { useClickAnyWhere } from
|
|
276
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
274
277
|
|
|
275
278
|
function CapturePhaseHandler() {
|
|
276
279
|
// Handle click before it reaches any element
|
|
277
280
|
useClickAnyWhere(
|
|
278
281
|
(event) => {
|
|
279
|
-
console.log(
|
|
282
|
+
console.log("Click captured (before bubble):", event.target);
|
|
280
283
|
},
|
|
281
284
|
{ capture: true }
|
|
282
285
|
);
|
|
@@ -288,8 +291,8 @@ function CapturePhaseHandler() {
|
|
|
288
291
|
### Tooltip Dismissal
|
|
289
292
|
|
|
290
293
|
```tsx
|
|
291
|
-
import { useClickAnyWhere } from
|
|
292
|
-
import { useState, useRef } from
|
|
294
|
+
import { useClickAnyWhere } from "@usefy/use-click-any-where";
|
|
295
|
+
import { useState, useRef } from "react";
|
|
293
296
|
|
|
294
297
|
function TooltipTrigger({ content }: { content: string }) {
|
|
295
298
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
@@ -297,7 +300,10 @@ function TooltipTrigger({ content }: { content: string }) {
|
|
|
297
300
|
|
|
298
301
|
useClickAnyWhere(
|
|
299
302
|
(event) => {
|
|
300
|
-
if (
|
|
303
|
+
if (
|
|
304
|
+
triggerRef.current &&
|
|
305
|
+
!triggerRef.current.contains(event.target as Node)
|
|
306
|
+
) {
|
|
301
307
|
setShowTooltip(false);
|
|
302
308
|
}
|
|
303
309
|
},
|
|
@@ -306,15 +312,10 @@ function TooltipTrigger({ content }: { content: string }) {
|
|
|
306
312
|
|
|
307
313
|
return (
|
|
308
314
|
<div className="tooltip-container">
|
|
309
|
-
<button
|
|
310
|
-
ref={triggerRef}
|
|
311
|
-
onClick={() => setShowTooltip(!showTooltip)}
|
|
312
|
-
>
|
|
315
|
+
<button ref={triggerRef} onClick={() => setShowTooltip(!showTooltip)}>
|
|
313
316
|
Show Info
|
|
314
317
|
</button>
|
|
315
|
-
{showTooltip &&
|
|
316
|
-
<div className="tooltip">{content}</div>
|
|
317
|
-
)}
|
|
318
|
+
{showTooltip && <div className="tooltip">{content}</div>}
|
|
318
319
|
</div>
|
|
319
320
|
);
|
|
320
321
|
}
|
|
@@ -331,11 +332,11 @@ import {
|
|
|
331
332
|
useClickAnyWhere,
|
|
332
333
|
type UseClickAnyWhereOptions,
|
|
333
334
|
type ClickAnyWhereHandler,
|
|
334
|
-
} from
|
|
335
|
+
} from "@usefy/use-click-any-where";
|
|
335
336
|
|
|
336
337
|
// Handler type
|
|
337
338
|
const handleClick: ClickAnyWhereHandler = (event) => {
|
|
338
|
-
console.log(
|
|
339
|
+
console.log("Clicked at:", event.clientX, event.clientY);
|
|
339
340
|
};
|
|
340
341
|
|
|
341
342
|
// Options type
|
|
@@ -356,18 +357,12 @@ This package maintains comprehensive test coverage to ensure reliability and sta
|
|
|
356
357
|
|
|
357
358
|
### Test Coverage
|
|
358
359
|
|
|
359
|
-
| Category |
|
|
360
|
-
|
|
361
|
-
|
|
|
362
|
-
|
|
|
363
|
-
|
|
|
364
|
-
|
|
|
365
|
-
| Cleanup | 2 | 100% |
|
|
366
|
-
| Handler Stability | 2 | 100% |
|
|
367
|
-
| Multiple Instances | 2 | 100% |
|
|
368
|
-
| Options Changes | 2 | 100% |
|
|
369
|
-
| Edge Cases | 2 | 100% |
|
|
370
|
-
| **Total** | **23** | **92.3%** |
|
|
360
|
+
| Category | Coverage |
|
|
361
|
+
|----------|----------|
|
|
362
|
+
| Statements | 92.3% (12/13) |
|
|
363
|
+
| Branches | 87.5% (7/8) |
|
|
364
|
+
| Functions | 100% (4/4) |
|
|
365
|
+
| Lines | 92.3% (12/13) |
|
|
371
366
|
|
|
372
367
|
### Test Categories
|
|
373
368
|
|
|
@@ -418,14 +413,14 @@ pnpm test --coverage
|
|
|
418
413
|
|
|
419
414
|
Explore other hooks in the **@usefy** collection:
|
|
420
415
|
|
|
421
|
-
| Package
|
|
422
|
-
|
|
423
|
-
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle)
|
|
424
|
-
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter)
|
|
425
|
-
| [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce)
|
|
426
|
-
| [@usefy/use-debounce-callback](https://www.npmjs.com/package/@usefy/use-debounce-callback) | Debounced callbacks
|
|
427
|
-
| [@usefy/use-throttle](https://www.npmjs.com/package/@usefy/use-throttle)
|
|
428
|
-
| [@usefy/use-throttle-callback](https://www.npmjs.com/package/@usefy/use-throttle-callback) | Throttled callbacks
|
|
416
|
+
| Package | Description |
|
|
417
|
+
| ------------------------------------------------------------------------------------------ | ------------------------ |
|
|
418
|
+
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
|
|
419
|
+
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
|
|
420
|
+
| [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) | Value debouncing |
|
|
421
|
+
| [@usefy/use-debounce-callback](https://www.npmjs.com/package/@usefy/use-debounce-callback) | Debounced callbacks |
|
|
422
|
+
| [@usefy/use-throttle](https://www.npmjs.com/package/@usefy/use-throttle) | Value throttling |
|
|
423
|
+
| [@usefy/use-throttle-callback](https://www.npmjs.com/package/@usefy/use-throttle-callback) | Throttled callbacks |
|
|
429
424
|
|
|
430
425
|
---
|
|
431
426
|
|