@sohanemon/utils 4.0.15 → 4.0.17
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/components/index.d.ts +3 -3
- package/dist/components/index.js +4 -4
- package/dist/components/media-wrapper.d.ts +6 -4
- package/dist/components/media-wrapper.js +12 -8
- package/dist/components/responsive-indicator.d.ts +1 -1
- package/dist/components/responsive-indicator.js +30 -30
- package/dist/functions/index.d.ts +2 -0
- package/dist/functions/index.js +18 -0
- package/dist/hooks/index.d.ts +18 -2
- package/dist/hooks/index.js +63 -25
- package/package.json +12 -9
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Icon as Iconify } from
|
|
2
|
-
export { MediaWrapper } from
|
|
3
|
-
export { ResponsiveIndicator, ResponsiveIndicator as TailwindIndicator, } from
|
|
1
|
+
export { Icon as Iconify } from '@iconify/react';
|
|
2
|
+
export { MediaWrapper } from './media-wrapper';
|
|
3
|
+
export { ResponsiveIndicator, ResponsiveIndicator as TailwindIndicator, } from './responsive-indicator';
|
package/dist/components/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export { Icon as Iconify } from
|
|
3
|
-
export { MediaWrapper } from
|
|
4
|
-
export { ResponsiveIndicator, ResponsiveIndicator as TailwindIndicator, } from
|
|
1
|
+
'use client';
|
|
2
|
+
export { Icon as Iconify } from '@iconify/react';
|
|
3
|
+
export { MediaWrapper } from './media-wrapper';
|
|
4
|
+
export { ResponsiveIndicator, ResponsiveIndicator as TailwindIndicator, } from './responsive-indicator';
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
type BreakPoints =
|
|
3
|
-
type MediaWrapperProps = React.ComponentProps<
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
type BreakPoints = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'max-sm' | 'max-md' | 'max-lg' | 'max-xl' | 'max-2xl';
|
|
3
|
+
type MediaWrapperProps = React.ComponentProps<'div'> & {
|
|
4
4
|
breakpoint: BreakPoints;
|
|
5
5
|
as?: React.ElementType;
|
|
6
|
+
fallback?: React.ElementType;
|
|
7
|
+
classNameFallback?: string;
|
|
6
8
|
};
|
|
7
|
-
export declare function MediaWrapper({ breakpoint, as, ...props }: MediaWrapperProps): any;
|
|
9
|
+
export declare function MediaWrapper({ breakpoint, as, fallback, classNameFallback, className: classNameOriginal, ...props }: MediaWrapperProps): any;
|
|
8
10
|
export {};
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from
|
|
4
|
-
import { useMediaQuery } from
|
|
5
|
-
export function MediaWrapper({ breakpoint, as =
|
|
6
|
-
const overMedia = useMediaQuery(breakpoint.split(
|
|
7
|
-
const isMax = breakpoint.startsWith(
|
|
8
|
-
const
|
|
9
|
-
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useMediaQuery } from '../hooks';
|
|
5
|
+
export function MediaWrapper({ breakpoint, as = 'div', fallback = React.Fragment, classNameFallback, className: classNameOriginal, ...props }) {
|
|
6
|
+
const overMedia = useMediaQuery(breakpoint.split('-').pop());
|
|
7
|
+
const isMax = breakpoint.startsWith('max');
|
|
8
|
+
const useFallback = overMedia === isMax;
|
|
9
|
+
// Conditionally determining which component to render,
|
|
10
|
+
// and what className should be passed to it.
|
|
11
|
+
const Wrapper = useFallback ? fallback : as;
|
|
12
|
+
const className = useFallback ? classNameFallback : classNameOriginal;
|
|
13
|
+
return _jsx(Wrapper, { className: className, ...props });
|
|
10
14
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import * as React from
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
export declare const ResponsiveIndicator: React.FC;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from
|
|
3
|
+
import * as React from 'react';
|
|
4
4
|
export const ResponsiveIndicator = () => {
|
|
5
5
|
const [viewportWidth, setViewportWidth] = React.useState(window.innerWidth);
|
|
6
6
|
const [position, setPosition] = React.useState(0); // State to manage button position
|
|
@@ -8,60 +8,60 @@ export const ResponsiveIndicator = () => {
|
|
|
8
8
|
const handleResize = () => {
|
|
9
9
|
setViewportWidth(window.innerWidth);
|
|
10
10
|
};
|
|
11
|
-
window.addEventListener(
|
|
11
|
+
window.addEventListener('resize', handleResize);
|
|
12
12
|
return () => {
|
|
13
|
-
window.removeEventListener(
|
|
13
|
+
window.removeEventListener('resize', handleResize);
|
|
14
14
|
};
|
|
15
15
|
}, []);
|
|
16
16
|
// Function to handle button click
|
|
17
17
|
const handleClick = () => {
|
|
18
18
|
setPosition((prevPosition) => (prevPosition + 1) % 4); // Cycle through positions
|
|
19
19
|
};
|
|
20
|
-
let text =
|
|
20
|
+
let text = '';
|
|
21
21
|
if (viewportWidth < 640) {
|
|
22
|
-
text =
|
|
22
|
+
text = 'xs';
|
|
23
23
|
}
|
|
24
24
|
else if (viewportWidth >= 640 && viewportWidth < 768) {
|
|
25
|
-
text =
|
|
25
|
+
text = 'sm';
|
|
26
26
|
}
|
|
27
27
|
else if (viewportWidth >= 768 && viewportWidth < 1024) {
|
|
28
|
-
text =
|
|
28
|
+
text = 'md';
|
|
29
29
|
}
|
|
30
30
|
else if (viewportWidth >= 1024 && viewportWidth < 1280) {
|
|
31
|
-
text =
|
|
31
|
+
text = 'lg';
|
|
32
32
|
}
|
|
33
33
|
else if (viewportWidth >= 1280 && viewportWidth < 1536) {
|
|
34
|
-
text =
|
|
34
|
+
text = 'xl';
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
text =
|
|
37
|
+
text = '2xl';
|
|
38
38
|
}
|
|
39
39
|
// Define positions
|
|
40
40
|
const positions = [
|
|
41
|
-
{ bottom:
|
|
42
|
-
{ bottom:
|
|
43
|
-
{ top:
|
|
44
|
-
{ top:
|
|
41
|
+
{ bottom: '2rem', left: '2rem' }, // Bottom left
|
|
42
|
+
{ bottom: '2rem', right: '2rem' }, // Bottom right
|
|
43
|
+
{ top: '2rem', right: '2rem' }, // Top right
|
|
44
|
+
{ top: '2rem', left: '2rem' }, // Top left
|
|
45
45
|
];
|
|
46
46
|
const buttonStyle = {
|
|
47
|
-
position:
|
|
47
|
+
position: 'fixed',
|
|
48
48
|
zIndex: 50,
|
|
49
|
-
display:
|
|
50
|
-
height:
|
|
51
|
-
width:
|
|
52
|
-
borderRadius:
|
|
53
|
-
placeContent:
|
|
54
|
-
backgroundColor:
|
|
55
|
-
fontFamily:
|
|
56
|
-
fontSize:
|
|
57
|
-
color:
|
|
58
|
-
border:
|
|
59
|
-
boxShadow:
|
|
60
|
-
padding:
|
|
61
|
-
transition:
|
|
49
|
+
display: 'grid',
|
|
50
|
+
height: '2.5rem',
|
|
51
|
+
width: '2.5rem',
|
|
52
|
+
borderRadius: '50%',
|
|
53
|
+
placeContent: 'center',
|
|
54
|
+
backgroundColor: '#2d3748',
|
|
55
|
+
fontFamily: 'Courier New, Courier, monospace',
|
|
56
|
+
fontSize: '1rem',
|
|
57
|
+
color: '#ffffff',
|
|
58
|
+
border: '2px solid #4a5568',
|
|
59
|
+
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
|
60
|
+
padding: '0.5rem',
|
|
61
|
+
transition: 'all 0.2s ease-in-out',
|
|
62
62
|
...positions[position], // Apply the current position
|
|
63
63
|
};
|
|
64
|
-
if (process.env.NODE_ENV ===
|
|
64
|
+
if (process.env.NODE_ENV === 'production')
|
|
65
65
|
return null;
|
|
66
66
|
return (_jsx("button", { type: "button", style: buttonStyle, onClick: handleClick, children: text }));
|
|
67
67
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ClassValue } from 'clsx';
|
|
2
|
+
import type * as React from 'react';
|
|
2
3
|
export declare function cn(...inputs: ClassValue[]): string;
|
|
3
4
|
export declare function isNavActive(href: string, path: string): boolean;
|
|
4
5
|
export declare function cleanSrc(src: string): string;
|
|
6
|
+
export declare const scrollTo: (containerSelector: string | React.RefObject<HTMLDivElement>, to: "top" | "bottom") => void;
|
package/dist/functions/index.js
CHANGED
|
@@ -12,3 +12,21 @@ export function cleanSrc(src) {
|
|
|
12
12
|
return src.replace('/public/', '/');
|
|
13
13
|
return src;
|
|
14
14
|
}
|
|
15
|
+
export const scrollTo = (containerSelector, to) => {
|
|
16
|
+
let container;
|
|
17
|
+
if (typeof containerSelector === 'string') {
|
|
18
|
+
container = document.querySelector(containerSelector);
|
|
19
|
+
}
|
|
20
|
+
else if (containerSelector.current) {
|
|
21
|
+
container = containerSelector.current;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (container) {
|
|
27
|
+
container.scrollTo({
|
|
28
|
+
top: to === 'top' ? 0 : container.scrollHeight - container.clientHeight,
|
|
29
|
+
behavior: 'smooth',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type Dispatch, type EffectCallback, type SetStateAction } from
|
|
1
|
+
import { type Dispatch, type EffectCallback, type SetStateAction } from 'react';
|
|
2
2
|
export declare const useClickOutside: (callback?: () => void) => any;
|
|
3
|
-
export declare function useMediaQuery(tailwindBreakpoint:
|
|
3
|
+
export declare function useMediaQuery(tailwindBreakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | `(${string})`): any;
|
|
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;
|
|
@@ -10,4 +10,20 @@ export declare function useWindowEvent<K extends string = keyof WindowEventMap>(
|
|
|
10
10
|
type LocalStorageValue<T> = [T, Dispatch<SetStateAction<T>>];
|
|
11
11
|
export declare const useLocalStorage: <T extends Record<string, any>>(key: string, defaultValue: T) => LocalStorageValue<T>;
|
|
12
12
|
export declare const useUrlParams: <T extends string | number | boolean>(key: string, defaultValue: T) => [T, (value: T) => void];
|
|
13
|
+
interface UseAsyncOptions<T extends (...args: any) => any> {
|
|
14
|
+
initialArgs?: Parameters<T>[0];
|
|
15
|
+
callback?: {
|
|
16
|
+
onSuccess?: (result: T) => void;
|
|
17
|
+
onError?: (error: Error) => void;
|
|
18
|
+
onExecute?: () => void;
|
|
19
|
+
onSettle?: () => void;
|
|
20
|
+
};
|
|
21
|
+
mode?: 'onLoad' | 'onTrigger';
|
|
22
|
+
}
|
|
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;
|
|
28
|
+
};
|
|
13
29
|
export {};
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { useEffect, useLayoutEffect, useMemo, useRef, useState, } from
|
|
3
|
-
export const useClickOutside = (callback = () => alert(
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useLayoutEffect, useMemo, useTransition, useCallback, useRef, useState, } from 'react';
|
|
3
|
+
export const useClickOutside = (callback = () => alert('clicked outside')) => {
|
|
4
4
|
const ref = useRef(null);
|
|
5
5
|
const listener = (e) => {
|
|
6
6
|
if (ref.current && !ref.current.contains(e.target)) {
|
|
@@ -8,11 +8,11 @@ export const useClickOutside = (callback = () => alert("clicked outside")) => {
|
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
10
|
useEffect(() => {
|
|
11
|
-
document.addEventListener(
|
|
12
|
-
document.addEventListener(
|
|
11
|
+
document.addEventListener('mousedown', listener);
|
|
12
|
+
document.addEventListener('touchstart', listener);
|
|
13
13
|
return () => {
|
|
14
|
-
document.removeEventListener(
|
|
15
|
-
document.removeEventListener(
|
|
14
|
+
document.removeEventListener('mousedown', listener);
|
|
15
|
+
document.removeEventListener('touchstart', listener);
|
|
16
16
|
};
|
|
17
17
|
});
|
|
18
18
|
return ref;
|
|
@@ -20,22 +20,22 @@ export const useClickOutside = (callback = () => alert("clicked outside")) => {
|
|
|
20
20
|
export function useMediaQuery(tailwindBreakpoint) {
|
|
21
21
|
const parsedQuery = useMemo(() => {
|
|
22
22
|
switch (tailwindBreakpoint) {
|
|
23
|
-
case
|
|
24
|
-
return
|
|
25
|
-
case
|
|
26
|
-
return
|
|
27
|
-
case
|
|
28
|
-
return
|
|
29
|
-
case
|
|
30
|
-
return
|
|
31
|
-
case
|
|
32
|
-
return
|
|
23
|
+
case 'sm':
|
|
24
|
+
return '(min-width: 640px)';
|
|
25
|
+
case 'md':
|
|
26
|
+
return '(min-width: 768px)';
|
|
27
|
+
case 'lg':
|
|
28
|
+
return '(min-width: 1024px)';
|
|
29
|
+
case 'xl':
|
|
30
|
+
return '(min-width: 1280px)';
|
|
31
|
+
case '2xl':
|
|
32
|
+
return '(min-width: 1536px)';
|
|
33
33
|
default:
|
|
34
34
|
return tailwindBreakpoint;
|
|
35
35
|
}
|
|
36
36
|
}, [tailwindBreakpoint]);
|
|
37
37
|
const getMatches = (parsedQuery) => {
|
|
38
|
-
if (typeof window !==
|
|
38
|
+
if (typeof window !== 'undefined') {
|
|
39
39
|
return window.matchMedia(parsedQuery).matches;
|
|
40
40
|
}
|
|
41
41
|
return false;
|
|
@@ -47,16 +47,14 @@ export function useMediaQuery(tailwindBreakpoint) {
|
|
|
47
47
|
useEffect(() => {
|
|
48
48
|
const matchMedia = window.matchMedia(parsedQuery);
|
|
49
49
|
handleChange();
|
|
50
|
-
matchMedia.addEventListener(
|
|
50
|
+
matchMedia.addEventListener('change', handleChange);
|
|
51
51
|
return () => {
|
|
52
|
-
matchMedia.removeEventListener(
|
|
52
|
+
matchMedia.removeEventListener('change', handleChange);
|
|
53
53
|
};
|
|
54
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
54
|
}, [parsedQuery]);
|
|
56
55
|
return matches;
|
|
57
56
|
}
|
|
58
57
|
export function useEffectOnce(effect) {
|
|
59
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
58
|
useEffect(effect, []);
|
|
61
59
|
}
|
|
62
60
|
export function useUpdateEffect(effect, deps) {
|
|
@@ -81,7 +79,7 @@ export function useDebounce(state, delay = 500) {
|
|
|
81
79
|
}, [state, delay]);
|
|
82
80
|
return debouncedState;
|
|
83
81
|
}
|
|
84
|
-
export const useIsomorphicEffect = typeof window !==
|
|
82
|
+
export const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
85
83
|
export function useTimeout(callback, delay = 1000) {
|
|
86
84
|
const savedCallback = useRef(callback);
|
|
87
85
|
useIsomorphicEffect(() => {
|
|
@@ -114,7 +112,7 @@ export const useLocalStorage = (key, defaultValue) => {
|
|
|
114
112
|
// Function to update the stored value in local storage and state
|
|
115
113
|
const updateStoredValue = (valueOrFn) => {
|
|
116
114
|
let newValue;
|
|
117
|
-
if (typeof valueOrFn ===
|
|
115
|
+
if (typeof valueOrFn === 'function') {
|
|
118
116
|
const updateFunction = valueOrFn;
|
|
119
117
|
newValue = updateFunction(storedValue);
|
|
120
118
|
}
|
|
@@ -141,8 +139,48 @@ export const useUrlParams = (key, defaultValue) => {
|
|
|
141
139
|
const updateValue = (newValue) => {
|
|
142
140
|
const params = new URLSearchParams(window.location.search);
|
|
143
141
|
params.set(key, String(newValue));
|
|
144
|
-
window.history.pushState({},
|
|
142
|
+
window.history.pushState({}, '', `${window.location.pathname}?${params}`);
|
|
145
143
|
setValue(newValue);
|
|
146
144
|
};
|
|
147
145
|
return [value, updateValue];
|
|
148
146
|
};
|
|
147
|
+
export const useAsync = (fn, opts = {}) => {
|
|
148
|
+
const { initialArgs, callback = {}, mode = "onTrigger" } = opts;
|
|
149
|
+
const { onSuccess, onError, onExecute, onSettle } = callback;
|
|
150
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
151
|
+
const [result, setValue] = useState(null);
|
|
152
|
+
const [error, setError] = useState(null);
|
|
153
|
+
const [isPending, startTransition] = useTransition();
|
|
154
|
+
const execute = useCallback(async (args) => {
|
|
155
|
+
setIsLoading(true);
|
|
156
|
+
setValue(null);
|
|
157
|
+
setError(null);
|
|
158
|
+
onExecute?.();
|
|
159
|
+
try {
|
|
160
|
+
startTransition(async () => {
|
|
161
|
+
const response = await fn(args);
|
|
162
|
+
setValue(response);
|
|
163
|
+
onSuccess?.(response);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
setError(error);
|
|
168
|
+
onError?.(error);
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
setIsLoading(false);
|
|
172
|
+
onSettle?.();
|
|
173
|
+
}
|
|
174
|
+
}, [fn, onExecute, onSuccess, onError, onSettle]);
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
if (mode === 'onLoad') {
|
|
177
|
+
execute(initialArgs);
|
|
178
|
+
}
|
|
179
|
+
}, []);
|
|
180
|
+
return {
|
|
181
|
+
execute,
|
|
182
|
+
isLoading: isLoading || isPending,
|
|
183
|
+
result,
|
|
184
|
+
error,
|
|
185
|
+
};
|
|
186
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sohanemon/utils",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.17",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -8,12 +8,15 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./dist/index.js",
|
|
11
|
+
"./core": "./dist/index.js",
|
|
11
12
|
"./hooks": "./dist/hooks/index.js",
|
|
12
|
-
"./components": "./dist/components/index.js"
|
|
13
|
-
"./package.json": "./package.json"
|
|
13
|
+
"./components": "./dist/components/index.js"
|
|
14
14
|
},
|
|
15
15
|
"typesVersions": {
|
|
16
16
|
"*": {
|
|
17
|
+
"core": [
|
|
18
|
+
"dist/index.d.ts"
|
|
19
|
+
],
|
|
17
20
|
"hooks": [
|
|
18
21
|
"dist/hooks/index.d.ts"
|
|
19
22
|
],
|
|
@@ -26,6 +29,11 @@
|
|
|
26
29
|
"dist",
|
|
27
30
|
"README.md"
|
|
28
31
|
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"build:watch": "tsc --watch",
|
|
35
|
+
"export": "tsc && npm publish"
|
|
36
|
+
},
|
|
29
37
|
"keywords": [
|
|
30
38
|
"utils",
|
|
31
39
|
"cn"
|
|
@@ -40,10 +48,5 @@
|
|
|
40
48
|
"clsx": "^2.0.0",
|
|
41
49
|
"react": "^18.2.0",
|
|
42
50
|
"tailwind-merge": "^1.14.0"
|
|
43
|
-
},
|
|
44
|
-
"scripts": {
|
|
45
|
-
"build": "tsc",
|
|
46
|
-
"build:watch": "tsc --watch",
|
|
47
|
-
"export": "tsc && npm publish"
|
|
48
51
|
}
|
|
49
|
-
}
|
|
52
|
+
}
|