@sohanemon/utils 4.0.25 → 4.0.27
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/dist/functions/index.d.ts +1 -0
- package/dist/functions/index.js +9 -0
- package/dist/hooks/index.d.ts +18 -6
- package/dist/hooks/index.js +53 -25
- package/package.json +18 -6
|
@@ -5,3 +5,4 @@ export declare function cn(...inputs: ClassValue[]): string;
|
|
|
5
5
|
export declare function isNavActive(href: string, path: string): boolean;
|
|
6
6
|
export declare function cleanSrc(src: string): string;
|
|
7
7
|
export declare const scrollTo: (containerSelector: string | React.RefObject<HTMLDivElement>, to: "top" | "bottom") => void;
|
|
8
|
+
export declare const copyToClipboard: (value: string, onSuccess?: () => void) => void;
|
package/dist/functions/index.js
CHANGED
|
@@ -33,3 +33,12 @@ export const scrollTo = (containerSelector, to) => {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
|
+
export const copyToClipboard = (value, onSuccess = () => { }) => {
|
|
37
|
+
if (typeof window === 'undefined' || !navigator.clipboard?.writeText) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!value) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
navigator.clipboard.writeText(value).then(onSuccess);
|
|
44
|
+
};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
export * from './action';
|
|
3
|
-
export declare const useClickOutside: (callback?: () => void) =>
|
|
3
|
+
export declare const useClickOutside: (callback?: () => void) => React.MutableRefObject<HTMLDivElement>;
|
|
4
4
|
export declare function useMediaQuery(tailwindBreakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | `(${string})`): boolean;
|
|
5
|
-
export declare function useEffectOnce(effect: EffectCallback): void;
|
|
6
|
-
export declare function useUpdateEffect(effect: EffectCallback, deps: any[]): void;
|
|
5
|
+
export declare function useEffectOnce(effect: React.EffectCallback): void;
|
|
6
|
+
export declare function useUpdateEffect(effect: React.EffectCallback, deps: any[]): void;
|
|
7
7
|
export declare function useDebounce<T>(state: T, delay?: number): T;
|
|
8
|
-
export declare const useIsomorphicEffect: typeof useLayoutEffect;
|
|
8
|
+
export declare const useIsomorphicEffect: typeof React.useLayoutEffect;
|
|
9
9
|
export declare function useTimeout(callback: () => void, delay?: number | null): void;
|
|
10
10
|
export declare function useWindowEvent<K extends string = keyof WindowEventMap>(type: K, listener: K extends keyof WindowEventMap ? (this: Window, ev: WindowEventMap[K]) => void : (this: Window, ev: CustomEvent) => void, options?: boolean | AddEventListenerOptions): void;
|
|
11
|
-
type LocalStorageValue<T> = [T, Dispatch<SetStateAction<T>>];
|
|
11
|
+
type LocalStorageValue<T> = [T, React.Dispatch<React.SetStateAction<T>>];
|
|
12
12
|
export declare const useLocalStorage: <T extends Record<string, any>>(key: string, defaultValue: T) => LocalStorageValue<T>;
|
|
13
13
|
export declare const useUrlParams: <T extends string | number | boolean>(key: string, defaultValue: T) => [T, (value: T) => void];
|
|
14
14
|
export declare const useQuerySelector: <T extends Element>(selector: string) => T | null;
|
|
15
15
|
export declare function useIsClient(): boolean;
|
|
16
16
|
export declare function useLockScroll(): void;
|
|
17
|
+
export declare function useCopyToClipboard({ timeout }: {
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}): {
|
|
20
|
+
isCopied: Boolean;
|
|
21
|
+
copy: (value: string) => void;
|
|
22
|
+
};
|
|
23
|
+
type CalculationProps = {
|
|
24
|
+
blockIds: string[];
|
|
25
|
+
dynamic?: boolean;
|
|
26
|
+
margin?: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const useHeightCalculation: ({ blockIds, margin, dynamic, }: CalculationProps) => number;
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { copyToClipboard } from '../functions';
|
|
3
|
+
import * as React from 'react';
|
|
3
4
|
export * from './action';
|
|
4
5
|
export const useClickOutside = (callback = () => alert('clicked outside')) => {
|
|
5
|
-
const ref = useRef(null);
|
|
6
|
+
const ref = React.useRef(null);
|
|
6
7
|
const listener = (e) => {
|
|
7
8
|
if (ref.current && !ref.current.contains(e.target)) {
|
|
8
9
|
callback();
|
|
9
10
|
}
|
|
10
11
|
};
|
|
11
|
-
useEffect(() => {
|
|
12
|
+
React.useEffect(() => {
|
|
12
13
|
document.addEventListener('mousedown', listener);
|
|
13
14
|
document.addEventListener('touchstart', listener);
|
|
14
15
|
return () => {
|
|
@@ -19,7 +20,7 @@ export const useClickOutside = (callback = () => alert('clicked outside')) => {
|
|
|
19
20
|
return ref;
|
|
20
21
|
};
|
|
21
22
|
export function useMediaQuery(tailwindBreakpoint) {
|
|
22
|
-
const parsedQuery = useMemo(() => {
|
|
23
|
+
const parsedQuery = React.useMemo(() => {
|
|
23
24
|
switch (tailwindBreakpoint) {
|
|
24
25
|
case 'sm':
|
|
25
26
|
return '(min-width: 640px)';
|
|
@@ -41,12 +42,12 @@ export function useMediaQuery(tailwindBreakpoint) {
|
|
|
41
42
|
}
|
|
42
43
|
return false;
|
|
43
44
|
};
|
|
44
|
-
const [matches, setMatches] = useState(getMatches(parsedQuery));
|
|
45
|
+
const [matches, setMatches] = React.useState(getMatches(parsedQuery));
|
|
45
46
|
function handleChange() {
|
|
46
47
|
setMatches(getMatches(parsedQuery));
|
|
47
48
|
}
|
|
48
49
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
49
|
-
useEffect(() => {
|
|
50
|
+
React.useEffect(() => {
|
|
50
51
|
const matchMedia = window.matchMedia(parsedQuery);
|
|
51
52
|
handleChange();
|
|
52
53
|
matchMedia.addEventListener('change', handleChange);
|
|
@@ -57,12 +58,12 @@ export function useMediaQuery(tailwindBreakpoint) {
|
|
|
57
58
|
return matches;
|
|
58
59
|
}
|
|
59
60
|
export function useEffectOnce(effect) {
|
|
60
|
-
useEffect(effect, []);
|
|
61
|
+
React.useEffect(effect, []);
|
|
61
62
|
}
|
|
62
63
|
export function useUpdateEffect(effect, deps) {
|
|
63
|
-
const isInitialMount = useRef(true);
|
|
64
|
+
const isInitialMount = React.useRef(true);
|
|
64
65
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
65
|
-
useEffect(() => {
|
|
66
|
+
React.useEffect(() => {
|
|
66
67
|
if (isInitialMount.current) {
|
|
67
68
|
isInitialMount.current = false;
|
|
68
69
|
}
|
|
@@ -72,8 +73,8 @@ export function useUpdateEffect(effect, deps) {
|
|
|
72
73
|
}, deps);
|
|
73
74
|
}
|
|
74
75
|
export function useDebounce(state, delay = 500) {
|
|
75
|
-
const [debouncedState, setDebouncedState] = useState(state);
|
|
76
|
-
useEffect(() => {
|
|
76
|
+
const [debouncedState, setDebouncedState] = React.useState(state);
|
|
77
|
+
React.useEffect(() => {
|
|
77
78
|
const timer = setTimeout(() => setDebouncedState(state), delay);
|
|
78
79
|
return () => {
|
|
79
80
|
clearTimeout(timer);
|
|
@@ -81,13 +82,13 @@ export function useDebounce(state, delay = 500) {
|
|
|
81
82
|
}, [state, delay]);
|
|
82
83
|
return debouncedState;
|
|
83
84
|
}
|
|
84
|
-
export const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
85
|
+
export const useIsomorphicEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
85
86
|
export function useTimeout(callback, delay = 1000) {
|
|
86
|
-
const savedCallback = useRef(callback);
|
|
87
|
+
const savedCallback = React.useRef(callback);
|
|
87
88
|
useIsomorphicEffect(() => {
|
|
88
89
|
savedCallback.current = callback;
|
|
89
90
|
}, [callback]);
|
|
90
|
-
useEffect(() => {
|
|
91
|
+
React.useEffect(() => {
|
|
91
92
|
if (!delay && delay !== 0) {
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
@@ -97,16 +98,16 @@ export function useTimeout(callback, delay = 1000) {
|
|
|
97
98
|
}
|
|
98
99
|
export function useWindowEvent(type, listener, options) {
|
|
99
100
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
100
|
-
useEffect(() => {
|
|
101
|
+
React.useEffect(() => {
|
|
101
102
|
window.addEventListener(type, listener, options);
|
|
102
103
|
return () => window.removeEventListener(type, listener, options);
|
|
103
104
|
}, [type, listener]);
|
|
104
105
|
}
|
|
105
106
|
// Custom hook for using local storage with a specified key and default value
|
|
106
107
|
export const useLocalStorage = (key, defaultValue) => {
|
|
107
|
-
const [storedValue, setStoredValue] = useState(defaultValue);
|
|
108
|
+
const [storedValue, setStoredValue] = React.useState(defaultValue);
|
|
108
109
|
// Use effect to retrieve the stored value from local storage on component mount
|
|
109
|
-
useEffect(() => {
|
|
110
|
+
React.useEffect(() => {
|
|
110
111
|
const value = localStorage.getItem(key);
|
|
111
112
|
if (value) {
|
|
112
113
|
setStoredValue(JSON.parse(value));
|
|
@@ -130,9 +131,9 @@ export const useLocalStorage = (key, defaultValue) => {
|
|
|
130
131
|
};
|
|
131
132
|
// Custom hook for using URL parameters with a specified key and default value
|
|
132
133
|
export const useUrlParams = (key, defaultValue) => {
|
|
133
|
-
const [value, setValue] = useState(defaultValue);
|
|
134
|
+
const [value, setValue] = React.useState(defaultValue);
|
|
134
135
|
// Use effect to retrieve the value from URL parameters on component mount
|
|
135
|
-
useEffect(() => {
|
|
136
|
+
React.useEffect(() => {
|
|
136
137
|
const params = new URLSearchParams(window.location.search);
|
|
137
138
|
const value = params.get(key);
|
|
138
139
|
if (value !== null) {
|
|
@@ -149,9 +150,9 @@ export const useUrlParams = (key, defaultValue) => {
|
|
|
149
150
|
return [value, updateValue];
|
|
150
151
|
};
|
|
151
152
|
export const useQuerySelector = (selector) => {
|
|
152
|
-
const [element, setElement] = useState(null);
|
|
153
|
-
const elementRef = useRef(null);
|
|
154
|
-
useLayoutEffect(() => {
|
|
153
|
+
const [element, setElement] = React.useState(null);
|
|
154
|
+
const elementRef = React.useRef(null);
|
|
155
|
+
React.useLayoutEffect(() => {
|
|
155
156
|
const referenceElement = document.querySelector(selector);
|
|
156
157
|
if (!referenceElement)
|
|
157
158
|
return;
|
|
@@ -174,14 +175,14 @@ export const useQuerySelector = (selector) => {
|
|
|
174
175
|
return element;
|
|
175
176
|
};
|
|
176
177
|
export function useIsClient() {
|
|
177
|
-
const [isClient, setIsClient] = useState(false);
|
|
178
|
-
useEffect(() => {
|
|
178
|
+
const [isClient, setIsClient] = React.useState(false);
|
|
179
|
+
React.useEffect(() => {
|
|
179
180
|
setIsClient(true);
|
|
180
181
|
}, []);
|
|
181
182
|
return isClient;
|
|
182
183
|
}
|
|
183
184
|
export function useLockScroll() {
|
|
184
|
-
useLayoutEffect(() => {
|
|
185
|
+
React.useLayoutEffect(() => {
|
|
185
186
|
const originalStyle = window.getComputedStyle(document.body).overflow;
|
|
186
187
|
document.body.style.overflow = 'hidden';
|
|
187
188
|
return () => {
|
|
@@ -189,3 +190,30 @@ export function useLockScroll() {
|
|
|
189
190
|
};
|
|
190
191
|
}, []);
|
|
191
192
|
}
|
|
193
|
+
export function useCopyToClipboard({ timeout = 2000 }) {
|
|
194
|
+
const [isCopied, setIsCopied] = React.useState(false);
|
|
195
|
+
const copy = (value) => {
|
|
196
|
+
copyToClipboard(value, () => {
|
|
197
|
+
setIsCopied(true);
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
setIsCopied(false);
|
|
200
|
+
}, timeout);
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
return { isCopied, copy };
|
|
204
|
+
}
|
|
205
|
+
export const useHeightCalculation = ({ blockIds = [], margin = 0, dynamic = false, }) => {
|
|
206
|
+
const [height, setTableHeight] = React.useState(500);
|
|
207
|
+
const handleResize = () => {
|
|
208
|
+
const blcokHeight = blockIds.reduce((prevHeight, id) => prevHeight + (document.getElementById(id)?.clientHeight || 0), 0);
|
|
209
|
+
setTableHeight(window.innerHeight - blcokHeight - margin);
|
|
210
|
+
};
|
|
211
|
+
useIsomorphicEffect(() => {
|
|
212
|
+
handleResize();
|
|
213
|
+
if (!dynamic)
|
|
214
|
+
return;
|
|
215
|
+
window.addEventListener('resize', handleResize);
|
|
216
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
217
|
+
}, []);
|
|
218
|
+
return height;
|
|
219
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sohanemon/utils",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.27",
|
|
4
4
|
"author": "Sohan Emon <sohanemon@outlook.com>",
|
|
5
5
|
"description": "",
|
|
6
6
|
"type": "module",
|
|
@@ -15,18 +15,30 @@
|
|
|
15
15
|
},
|
|
16
16
|
"typesVersions": {
|
|
17
17
|
"*": {
|
|
18
|
-
"core": [
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
"core": [
|
|
19
|
+
"dist/index.d.ts"
|
|
20
|
+
],
|
|
21
|
+
"hooks": [
|
|
22
|
+
"dist/hooks/index.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"components": [
|
|
25
|
+
"dist/components/index.d.ts"
|
|
26
|
+
]
|
|
21
27
|
}
|
|
22
28
|
},
|
|
23
|
-
"files": [
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
24
33
|
"scripts": {
|
|
25
34
|
"build": "tsc",
|
|
26
35
|
"build:watch": "tsc --watch",
|
|
27
36
|
"export": "tsc && npm publish"
|
|
28
37
|
},
|
|
29
|
-
"keywords": [
|
|
38
|
+
"keywords": [
|
|
39
|
+
"utils",
|
|
40
|
+
"cn"
|
|
41
|
+
],
|
|
30
42
|
"license": "ISC",
|
|
31
43
|
"devDependencies": {
|
|
32
44
|
"@types/node": "^22.4.0",
|