@sohanemon/utils 4.0.17 → 4.0.20

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.
@@ -6,5 +6,5 @@ type MediaWrapperProps = React.ComponentProps<'div'> & {
6
6
  fallback?: React.ElementType;
7
7
  classNameFallback?: string;
8
8
  };
9
- export declare function MediaWrapper({ breakpoint, as, fallback, classNameFallback, className: classNameOriginal, ...props }: MediaWrapperProps): any;
9
+ export declare function MediaWrapper({ breakpoint, as, fallback, classNameFallback, className: classNameOriginal, ...props }: MediaWrapperProps): import("react/jsx-runtime").JSX.Element;
10
10
  export {};
@@ -1,10 +1,10 @@
1
- import { type Dispatch, type EffectCallback, type SetStateAction } from 'react';
2
- export declare const useClickOutside: (callback?: () => void) => any;
3
- export declare function useMediaQuery(tailwindBreakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | `(${string})`): any;
1
+ import { type Dispatch, type EffectCallback, type SetStateAction, useEffect } from 'react';
2
+ export declare const useClickOutside: (callback?: () => void) => import("react").MutableRefObject<HTMLDivElement>;
3
+ export declare function useMediaQuery(tailwindBreakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | `(${string})`): boolean;
4
4
  export declare function useEffectOnce(effect: EffectCallback): void;
5
5
  export declare function useUpdateEffect(effect: EffectCallback, deps: any[]): void;
6
6
  export declare function useDebounce<T>(state: T, delay?: number): T;
7
- export declare const useIsomorphicEffect: any;
7
+ export declare const useIsomorphicEffect: typeof useEffect;
8
8
  export declare function useTimeout(callback: () => void, delay?: number | null): void;
9
9
  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;
10
10
  type LocalStorageValue<T> = [T, Dispatch<SetStateAction<T>>];
@@ -21,9 +21,11 @@ interface UseAsyncOptions<T extends (...args: any) => any> {
21
21
  mode?: 'onLoad' | 'onTrigger';
22
22
  }
23
23
  export declare const useAsync: <T extends (...args: any) => any>(fn: T, opts?: UseAsyncOptions<T>) => {
24
- execute: any;
25
- isLoading: any;
26
- result: any;
27
- error: any;
24
+ execute: (args: Parameters<T>[0]) => Promise<void>;
25
+ isLoading: boolean;
26
+ result: Awaited<ReturnType<T>>;
27
+ error: Error;
28
28
  };
29
+ export declare const useQuerySelector: <T extends Element>(selector: string) => T | null;
30
+ export declare function useIsClient(): boolean;
29
31
  export {};
@@ -44,6 +44,7 @@ export function useMediaQuery(tailwindBreakpoint) {
44
44
  function handleChange() {
45
45
  setMatches(getMatches(parsedQuery));
46
46
  }
47
+ // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
47
48
  useEffect(() => {
48
49
  const matchMedia = window.matchMedia(parsedQuery);
49
50
  handleChange();
@@ -59,6 +60,7 @@ export function useEffectOnce(effect) {
59
60
  }
60
61
  export function useUpdateEffect(effect, deps) {
61
62
  const isInitialMount = useRef(true);
63
+ // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
62
64
  useEffect(() => {
63
65
  if (isInitialMount.current) {
64
66
  isInitialMount.current = false;
@@ -66,7 +68,6 @@ export function useUpdateEffect(effect, deps) {
66
68
  else {
67
69
  return effect();
68
70
  }
69
- // eslint-disable-next-line react-hooks/exhaustive-deps
70
71
  }, deps);
71
72
  }
72
73
  export function useDebounce(state, delay = 500) {
@@ -94,6 +95,7 @@ export function useTimeout(callback, delay = 1000) {
94
95
  }, [delay]);
95
96
  }
96
97
  export function useWindowEvent(type, listener, options) {
98
+ // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
97
99
  useEffect(() => {
98
100
  window.addEventListener(type, listener, options);
99
101
  return () => window.removeEventListener(type, listener, options);
@@ -111,6 +113,7 @@ export const useLocalStorage = (key, defaultValue) => {
111
113
  }, [key]);
112
114
  // Function to update the stored value in local storage and state
113
115
  const updateStoredValue = (valueOrFn) => {
116
+ // biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>
114
117
  let newValue;
115
118
  if (typeof valueOrFn === 'function') {
116
119
  const updateFunction = valueOrFn;
@@ -145,7 +148,7 @@ export const useUrlParams = (key, defaultValue) => {
145
148
  return [value, updateValue];
146
149
  };
147
150
  export const useAsync = (fn, opts = {}) => {
148
- const { initialArgs, callback = {}, mode = "onTrigger" } = opts;
151
+ const { initialArgs, callback = {}, mode = 'onTrigger' } = opts;
149
152
  const { onSuccess, onError, onExecute, onSettle } = callback;
150
153
  const [isLoading, setIsLoading] = useState(false);
151
154
  const [result, setValue] = useState(null);
@@ -157,10 +160,12 @@ export const useAsync = (fn, opts = {}) => {
157
160
  setError(null);
158
161
  onExecute?.();
159
162
  try {
160
- startTransition(async () => {
161
- const response = await fn(args);
162
- setValue(response);
163
- onSuccess?.(response);
163
+ startTransition(() => {
164
+ (async () => {
165
+ const response = await fn(args);
166
+ setValue(response);
167
+ onSuccess?.(response);
168
+ })();
164
169
  });
165
170
  }
166
171
  catch (error) {
@@ -172,7 +177,7 @@ export const useAsync = (fn, opts = {}) => {
172
177
  onSettle?.();
173
178
  }
174
179
  }, [fn, onExecute, onSuccess, onError, onSettle]);
175
- useEffect(() => {
180
+ useIsomorphicEffect(() => {
176
181
  if (mode === 'onLoad') {
177
182
  execute(initialArgs);
178
183
  }
@@ -184,3 +189,35 @@ export const useAsync = (fn, opts = {}) => {
184
189
  error,
185
190
  };
186
191
  };
192
+ export const useQuerySelector = (selector) => {
193
+ const [element, setElement] = useState(null);
194
+ const elementRef = useRef(null);
195
+ useLayoutEffect(() => {
196
+ const referenceElement = document.querySelector(selector);
197
+ if (!referenceElement)
198
+ return;
199
+ if (elementRef.current !== referenceElement) {
200
+ elementRef.current = referenceElement;
201
+ setElement(referenceElement);
202
+ }
203
+ const resizeObserver = new ResizeObserver(() => {
204
+ // Only update state if the element reference changes
205
+ if (elementRef.current !== referenceElement) {
206
+ elementRef.current = referenceElement;
207
+ setElement(referenceElement);
208
+ }
209
+ });
210
+ resizeObserver.observe(referenceElement);
211
+ return () => {
212
+ resizeObserver.disconnect();
213
+ };
214
+ }, [selector]);
215
+ return element;
216
+ };
217
+ export function useIsClient() {
218
+ const [isClient, setIsClient] = useState(false);
219
+ useEffect(() => {
220
+ setIsClient(true);
221
+ }, []);
222
+ return isClient;
223
+ }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@sohanemon/utils",
3
- "version": "4.0.17",
3
+ "version": "4.0.20",
4
+ "author": "Sohan Emon <sohanemon@outlook.com>",
4
5
  "description": "",
5
6
  "type": "module",
6
7
  "source": "./src/index.ts",
@@ -38,15 +39,16 @@
38
39
  "utils",
39
40
  "cn"
40
41
  ],
41
- "author": "sohanemon",
42
42
  "license": "ISC",
43
43
  "devDependencies": {
44
- "typescript": "^5.2.2"
44
+ "@types/node": "^22.4.0",
45
+ "@types/react": "^18.3.3",
46
+ "typescript": "^5.5.4"
45
47
  },
46
48
  "dependencies": {
47
49
  "@iconify/react": "^4.1.1",
48
- "clsx": "^2.0.0",
49
- "react": "^18.2.0",
50
+ "clsx": "^2.1.1",
51
+ "react": "^18.3.1",
50
52
  "tailwind-merge": "^1.14.0"
51
53
  }
52
54
  }