@usefy/use-click-any-where 0.0.8

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,70 @@
1
+ /**
2
+ * Options for useClickAnyWhere hook
3
+ */
4
+ interface UseClickAnyWhereOptions {
5
+ /**
6
+ * Whether the event listener is enabled
7
+ * @default true
8
+ */
9
+ enabled?: boolean;
10
+ /**
11
+ * Whether to use event capture phase
12
+ * @default false
13
+ */
14
+ capture?: boolean;
15
+ /**
16
+ * Whether to use passive event listener
17
+ * @default true
18
+ */
19
+ passive?: boolean;
20
+ }
21
+ /**
22
+ * Handler type for click events
23
+ */
24
+ type ClickAnyWhereHandler = (event: MouseEvent) => void;
25
+ /**
26
+ * Detects document-wide click events and calls the provided handler.
27
+ * Useful for closing dropdowns, modals, or any component when clicking outside.
28
+ *
29
+ * @param handler - Callback function called when a click is detected anywhere on the document
30
+ * @param options - Configuration options for the event listener
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * function ClickTracker() {
35
+ * const [lastClick, setLastClick] = useState({ x: 0, y: 0 });
36
+ *
37
+ * useClickAnyWhere((event) => {
38
+ * setLastClick({ x: event.clientX, y: event.clientY });
39
+ * });
40
+ *
41
+ * return (
42
+ * <div>
43
+ * Last click: ({lastClick.x}, {lastClick.y})
44
+ * </div>
45
+ * );
46
+ * }
47
+ * ```
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * // Conditional activation
52
+ * function Dropdown({ isOpen, onClose }) {
53
+ * useClickAnyWhere(
54
+ * () => onClose(),
55
+ * { enabled: isOpen }
56
+ * );
57
+ *
58
+ * return isOpen ? <div>Dropdown content</div> : null;
59
+ * }
60
+ * ```
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * // With capture phase
65
+ * useClickAnyWhere(handleClick, { capture: true });
66
+ * ```
67
+ */
68
+ declare function useClickAnyWhere(handler: ClickAnyWhereHandler, options?: UseClickAnyWhereOptions): void;
69
+
70
+ export { type ClickAnyWhereHandler, type UseClickAnyWhereOptions, useClickAnyWhere };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Options for useClickAnyWhere hook
3
+ */
4
+ interface UseClickAnyWhereOptions {
5
+ /**
6
+ * Whether the event listener is enabled
7
+ * @default true
8
+ */
9
+ enabled?: boolean;
10
+ /**
11
+ * Whether to use event capture phase
12
+ * @default false
13
+ */
14
+ capture?: boolean;
15
+ /**
16
+ * Whether to use passive event listener
17
+ * @default true
18
+ */
19
+ passive?: boolean;
20
+ }
21
+ /**
22
+ * Handler type for click events
23
+ */
24
+ type ClickAnyWhereHandler = (event: MouseEvent) => void;
25
+ /**
26
+ * Detects document-wide click events and calls the provided handler.
27
+ * Useful for closing dropdowns, modals, or any component when clicking outside.
28
+ *
29
+ * @param handler - Callback function called when a click is detected anywhere on the document
30
+ * @param options - Configuration options for the event listener
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * function ClickTracker() {
35
+ * const [lastClick, setLastClick] = useState({ x: 0, y: 0 });
36
+ *
37
+ * useClickAnyWhere((event) => {
38
+ * setLastClick({ x: event.clientX, y: event.clientY });
39
+ * });
40
+ *
41
+ * return (
42
+ * <div>
43
+ * Last click: ({lastClick.x}, {lastClick.y})
44
+ * </div>
45
+ * );
46
+ * }
47
+ * ```
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * // Conditional activation
52
+ * function Dropdown({ isOpen, onClose }) {
53
+ * useClickAnyWhere(
54
+ * () => onClose(),
55
+ * { enabled: isOpen }
56
+ * );
57
+ *
58
+ * return isOpen ? <div>Dropdown content</div> : null;
59
+ * }
60
+ * ```
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * // With capture phase
65
+ * useClickAnyWhere(handleClick, { capture: true });
66
+ * ```
67
+ */
68
+ declare function useClickAnyWhere(handler: ClickAnyWhereHandler, options?: UseClickAnyWhereOptions): void;
69
+
70
+ export { type ClickAnyWhereHandler, type UseClickAnyWhereOptions, useClickAnyWhere };
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ useClickAnyWhere: () => useClickAnyWhere
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/useClickAnyWhere.ts
28
+ var import_react = require("react");
29
+ function useClickAnyWhere(handler, options = {}) {
30
+ const { enabled = true, capture = false, passive = true } = options;
31
+ const handlerRef = (0, import_react.useRef)(handler);
32
+ handlerRef.current = handler;
33
+ (0, import_react.useEffect)(() => {
34
+ if (typeof document === "undefined") {
35
+ return;
36
+ }
37
+ if (!enabled) {
38
+ return;
39
+ }
40
+ const internalHandler = (event) => {
41
+ handlerRef.current(event);
42
+ };
43
+ document.addEventListener("click", internalHandler, { capture, passive });
44
+ return () => {
45
+ document.removeEventListener("click", internalHandler, { capture });
46
+ };
47
+ }, [enabled, capture, passive]);
48
+ }
49
+ // Annotate the CommonJS export names for ESM import in node:
50
+ 0 && (module.exports = {
51
+ useClickAnyWhere
52
+ });
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/useClickAnyWhere.ts"],"sourcesContent":["export {\n useClickAnyWhere,\n type UseClickAnyWhereOptions,\n type ClickAnyWhereHandler,\n} from \"./useClickAnyWhere\";\n","import { useEffect, useRef } from \"react\";\n\n/**\n * Options for useClickAnyWhere hook\n */\nexport interface UseClickAnyWhereOptions {\n /**\n * Whether the event listener is enabled\n * @default true\n */\n enabled?: boolean;\n /**\n * Whether to use event capture phase\n * @default false\n */\n capture?: boolean;\n /**\n * Whether to use passive event listener\n * @default true\n */\n passive?: boolean;\n}\n\n/**\n * Handler type for click events\n */\nexport type ClickAnyWhereHandler = (event: MouseEvent) => void;\n\n/**\n * Detects document-wide click events and calls the provided handler.\n * Useful for closing dropdowns, modals, or any component when clicking outside.\n *\n * @param handler - Callback function called when a click is detected anywhere on the document\n * @param options - Configuration options for the event listener\n *\n * @example\n * ```tsx\n * function ClickTracker() {\n * const [lastClick, setLastClick] = useState({ x: 0, y: 0 });\n *\n * useClickAnyWhere((event) => {\n * setLastClick({ x: event.clientX, y: event.clientY });\n * });\n *\n * return (\n * <div>\n * Last click: ({lastClick.x}, {lastClick.y})\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Conditional activation\n * function Dropdown({ isOpen, onClose }) {\n * useClickAnyWhere(\n * () => onClose(),\n * { enabled: isOpen }\n * );\n *\n * return isOpen ? <div>Dropdown content</div> : null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With capture phase\n * useClickAnyWhere(handleClick, { capture: true });\n * ```\n */\nexport function useClickAnyWhere(\n handler: ClickAnyWhereHandler,\n options: UseClickAnyWhereOptions = {}\n): void {\n const { enabled = true, capture = false, passive = true } = options;\n\n // Store handler in ref to avoid re-registering event listener\n const handlerRef = useRef<ClickAnyWhereHandler>(handler);\n\n // Update ref when handler changes\n handlerRef.current = handler;\n\n useEffect(() => {\n // SSR check\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Don't add listener if disabled\n if (!enabled) {\n return;\n }\n\n // Internal handler that calls the latest handler ref\n const internalHandler = (event: MouseEvent) => {\n handlerRef.current(event);\n };\n\n // Add event listener\n document.addEventListener(\"click\", internalHandler, { capture, passive });\n\n // Cleanup\n return () => {\n document.removeEventListener(\"click\", internalHandler, { capture });\n };\n }, [enabled, capture, passive]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAkC;AAuE3B,SAAS,iBACd,SACA,UAAmC,CAAC,GAC9B;AACN,QAAM,EAAE,UAAU,MAAM,UAAU,OAAO,UAAU,KAAK,IAAI;AAG5D,QAAM,iBAAa,qBAA6B,OAAO;AAGvD,aAAW,UAAU;AAErB,8BAAU,MAAM;AAEd,QAAI,OAAO,aAAa,aAAa;AACnC;AAAA,IACF;AAGA,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAGA,UAAM,kBAAkB,CAAC,UAAsB;AAC7C,iBAAW,QAAQ,KAAK;AAAA,IAC1B;AAGA,aAAS,iBAAiB,SAAS,iBAAiB,EAAE,SAAS,QAAQ,CAAC;AAGxE,WAAO,MAAM;AACX,eAAS,oBAAoB,SAAS,iBAAiB,EAAE,QAAQ,CAAC;AAAA,IACpE;AAAA,EACF,GAAG,CAAC,SAAS,SAAS,OAAO,CAAC;AAChC;","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,26 @@
1
+ // src/useClickAnyWhere.ts
2
+ import { useEffect, useRef } from "react";
3
+ function useClickAnyWhere(handler, options = {}) {
4
+ const { enabled = true, capture = false, passive = true } = options;
5
+ const handlerRef = useRef(handler);
6
+ handlerRef.current = handler;
7
+ useEffect(() => {
8
+ if (typeof document === "undefined") {
9
+ return;
10
+ }
11
+ if (!enabled) {
12
+ return;
13
+ }
14
+ const internalHandler = (event) => {
15
+ handlerRef.current(event);
16
+ };
17
+ document.addEventListener("click", internalHandler, { capture, passive });
18
+ return () => {
19
+ document.removeEventListener("click", internalHandler, { capture });
20
+ };
21
+ }, [enabled, capture, passive]);
22
+ }
23
+ export {
24
+ useClickAnyWhere
25
+ };
26
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useClickAnyWhere.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/**\n * Options for useClickAnyWhere hook\n */\nexport interface UseClickAnyWhereOptions {\n /**\n * Whether the event listener is enabled\n * @default true\n */\n enabled?: boolean;\n /**\n * Whether to use event capture phase\n * @default false\n */\n capture?: boolean;\n /**\n * Whether to use passive event listener\n * @default true\n */\n passive?: boolean;\n}\n\n/**\n * Handler type for click events\n */\nexport type ClickAnyWhereHandler = (event: MouseEvent) => void;\n\n/**\n * Detects document-wide click events and calls the provided handler.\n * Useful for closing dropdowns, modals, or any component when clicking outside.\n *\n * @param handler - Callback function called when a click is detected anywhere on the document\n * @param options - Configuration options for the event listener\n *\n * @example\n * ```tsx\n * function ClickTracker() {\n * const [lastClick, setLastClick] = useState({ x: 0, y: 0 });\n *\n * useClickAnyWhere((event) => {\n * setLastClick({ x: event.clientX, y: event.clientY });\n * });\n *\n * return (\n * <div>\n * Last click: ({lastClick.x}, {lastClick.y})\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Conditional activation\n * function Dropdown({ isOpen, onClose }) {\n * useClickAnyWhere(\n * () => onClose(),\n * { enabled: isOpen }\n * );\n *\n * return isOpen ? <div>Dropdown content</div> : null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With capture phase\n * useClickAnyWhere(handleClick, { capture: true });\n * ```\n */\nexport function useClickAnyWhere(\n handler: ClickAnyWhereHandler,\n options: UseClickAnyWhereOptions = {}\n): void {\n const { enabled = true, capture = false, passive = true } = options;\n\n // Store handler in ref to avoid re-registering event listener\n const handlerRef = useRef<ClickAnyWhereHandler>(handler);\n\n // Update ref when handler changes\n handlerRef.current = handler;\n\n useEffect(() => {\n // SSR check\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Don't add listener if disabled\n if (!enabled) {\n return;\n }\n\n // Internal handler that calls the latest handler ref\n const internalHandler = (event: MouseEvent) => {\n handlerRef.current(event);\n };\n\n // Add event listener\n document.addEventListener(\"click\", internalHandler, { capture, passive });\n\n // Cleanup\n return () => {\n document.removeEventListener(\"click\", internalHandler, { capture });\n };\n }, [enabled, capture, passive]);\n}\n"],"mappings":";AAAA,SAAS,WAAW,cAAc;AAuE3B,SAAS,iBACd,SACA,UAAmC,CAAC,GAC9B;AACN,QAAM,EAAE,UAAU,MAAM,UAAU,OAAO,UAAU,KAAK,IAAI;AAG5D,QAAM,aAAa,OAA6B,OAAO;AAGvD,aAAW,UAAU;AAErB,YAAU,MAAM;AAEd,QAAI,OAAO,aAAa,aAAa;AACnC;AAAA,IACF;AAGA,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAGA,UAAM,kBAAkB,CAAC,UAAsB;AAC7C,iBAAW,QAAQ,KAAK;AAAA,IAC1B;AAGA,aAAS,iBAAiB,SAAS,iBAAiB,EAAE,SAAS,QAAQ,CAAC;AAGxE,WAAO,MAAM;AACX,eAAS,oBAAoB,SAAS,iBAAiB,EAAE,QAAQ,CAAC;AAAA,IACpE;AAAA,EACF,GAAG,CAAC,SAAS,SAAS,OAAO,CAAC;AAChC;","names":[]}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@usefy/use-click-any-where",
3
+ "version": "0.0.8",
4
+ "description": "A React hook for detecting document-wide click events",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "sideEffects": false,
19
+ "peerDependencies": {
20
+ "react": "^18.0.0 || ^19.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@testing-library/jest-dom": "^6.9.1",
24
+ "@testing-library/react": "^16.3.1",
25
+ "@testing-library/user-event": "^14.6.1",
26
+ "@types/react": "^19.0.0",
27
+ "jsdom": "^27.3.0",
28
+ "react": "^19.0.0",
29
+ "rimraf": "^6.0.1",
30
+ "tsup": "^8.0.0",
31
+ "typescript": "^5.0.0",
32
+ "vitest": "^4.0.16"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/geon0529/usefy.git",
40
+ "directory": "packages/use-click-any-where"
41
+ },
42
+ "license": "MIT",
43
+ "keywords": [
44
+ "react",
45
+ "hooks",
46
+ "click",
47
+ "document",
48
+ "event-listener",
49
+ "click-anywhere"
50
+ ],
51
+ "scripts": {
52
+ "build": "tsup",
53
+ "dev": "tsup --watch",
54
+ "test": "vitest run",
55
+ "test:watch": "vitest",
56
+ "typecheck": "tsc --noEmit",
57
+ "clean": "rimraf dist"
58
+ }
59
+ }