Skip to content

Commit e1c0a0a

Browse files
committed
main 🧊 up test coverage, add shallow effect
1 parent cf20c5c commit e1c0a0a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1395
-122
lines changed

‎README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
packages/core/README.md
1+
packages/core/README.md

‎packages/core/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ npm install @siberiacancode/reactuse
2525
```
2626

2727
```tsx
28-
import { useCounter } from "@siberiacancode/reactuse";
28+
import { useCounter } from '@siberiacancode/reactuse';
2929

30-
function App() {
30+
const App = () => {
3131
const counter = useCounter(0);
3232

3333
return (
@@ -37,7 +37,7 @@ function App() {
3737
<button onClick={() => counter.dec()}>-1</button>
3838
</div>
3939
);
40-
}
40+
};
4141
```
4242

4343
## CLI installation

‎packages/core/src/bundle/hooks/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ export * from './useScrollIntoView/useScrollIntoView';
108108
export * from './useScrollTo/useScrollTo';
109109
export * from './useSessionStorage/useSessionStorage';
110110
export * from './useSet/useSet';
111+
export * from './useShallowEffect/useShallowEffect';
111112
export * from './useShare/useShare';
112113
export * from './useSpeechRecognition/useSpeechRecognition';
113114
export * from './useSpeechSynthesis/useSpeechSynthesis';

‎packages/core/src/bundle/hooks/useCopy/useCopy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { copy } from '@/utils/helpers';
1414
* const { copied, value, copy } = useCopy();
1515
*/
1616
export const useCopy = (delay = 1000) => {
17-
const [value, setValue] = useState(null);
17+
const [value, setValue] = useState();
1818
const [copied, setCopied] = useState(false);
1919
const copyToClipboard = async (text) => {
2020
await copy(text);

‎packages/core/src/bundle/hooks/useCssVar/useCssVar.js

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useRefState } from '../useRefState/useRefState';
1212
* @returns {UseCssVarReturn & { ref: StateRef<Element> }} The object containing the value of the CSS variable and ref
1313
*
1414
* @example
15-
* const { ref, value, set } = useCssVar('--color', 'red');
15+
* const { ref, value, set, remove } = useCssVar('--color', 'red');
1616
*
1717
* @overload
1818
* @param {HookTarget} target The target element
@@ -21,7 +21,7 @@ import { useRefState } from '../useRefState/useRefState';
2121
* @returns {UseCssVarReturn} The object containing the value of the CSS variable
2222
*
2323
* @example
24-
* const { value, set } = useCssVar(ref, '--color', 'red');
24+
* const { value, set, remove } = useCssVar(ref, '--color', 'red');
2525
*/
2626
export const useCssVar = (...params) => {
2727
const target = isTarget(params[0]) ? params[0] : undefined;
@@ -31,16 +31,15 @@ export const useCssVar = (...params) => {
3131
const internalRef = useRefState(window.document.documentElement);
3232
const set = (value) => {
3333
const element = target ? getElement(target) : internalRef.current;
34-
if (!element) return;
35-
if (element.style) {
36-
if (!value) {
37-
element.style.removeProperty(key);
38-
setValue(value);
39-
return;
40-
}
41-
element.style.setProperty(key, value);
42-
setValue(value);
43-
}
34+
if (!element || !element.style) return;
35+
element.style.setProperty(key, value);
36+
setValue(value);
37+
};
38+
const remove = () => {
39+
const element = target ? getElement(target) : internalRef.current;
40+
if (!element || !element.style) return;
41+
element.style.removeProperty(key);
42+
setValue('');
4443
};
4544
useEffect(() => {
4645
if (initialValue) set(initialValue);
@@ -59,6 +58,6 @@ export const useCssVar = (...params) => {
5958
observer.disconnect();
6059
};
6160
}, [target, internalRef.state]);
62-
if (target) return { value, set };
63-
return { ref: internalRef, value, set };
61+
if (target) return { value, set, remove };
62+
return { ref: internalRef, value, set, remove };
6463
};

‎packages/core/src/bundle/hooks/useDebounceCallback/useDebounceCallback.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ export const useDebounceCallback = (callback, delay) => {
2121
delayRef.current = delay;
2222
const debounced = useMemo(() => {
2323
const cancel = () => {
24-
if (timerRef.current) {
25-
clearTimeout(timerRef.current);
26-
timerRef.current = undefined;
27-
}
24+
if (!timerRef.current) return;
25+
clearTimeout(timerRef.current);
26+
timerRef.current = null;
2827
};
2928
const debouncedCallback = function (...args) {
3029
cancel();

‎packages/core/src/bundle/hooks/useDoubleClick/useDoubleClick.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useRef } from 'react';
22
import { getElement, isTarget } from '@/utils/helpers';
33
import { useRefState } from '../useRefState/useRefState';
4-
const DEFAULT_THRESHOLD_TIME = 300;
4+
export const DEFAULT_THRESHOLD_TIME = 300;
55
/**
66
* @name useDoubleClick
77
* @description - Hook that defines the logic when double clicking an element

‎packages/core/src/bundle/hooks/useHash/useHash.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,28 @@ const getHash = () => decodeURIComponent(window.location.hash.replace('#', ''));
55
* @description - Hook that manages the hash value
66
* @category Browser
77
*
8+
* @param {string} [initialValue] The initial hash value if no hash exists
89
* @returns {UseHashReturn} An array containing the hash value and a function to set the hash value
910
*
1011
* @example
11-
* const [hash, setHash] = useHash();
12+
* const [hash, setHash] = useHash("initial");
1213
*/
13-
export const useHash = () => {
14-
const [hash, setHash] = useState(window ? getHash() : '');
14+
export const useHash = (initialValue = '', mode = 'replace') => {
15+
const [hash, setHash] = useState(() => {
16+
if (typeof window === 'undefined') return initialValue;
17+
return getHash() || initialValue;
18+
});
1519
const set = (value) => {
1620
window.location.hash = value;
1721
setHash(value);
1822
};
1923
useEffect(() => {
24+
if (mode === 'replace') window.location.hash = hash;
2025
const onHashChange = () => setHash(getHash());
2126
window.addEventListener('hashchange', onHashChange);
2227
return () => {
2328
window.removeEventListener('hashchange', onHashChange);
2429
};
25-
});
30+
}, []);
2631
return [hash, set];
2732
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useEffect, useRef } from 'react';
2+
export const deepEqual = (a, b) => {
3+
if (a === b) return true;
4+
if (a == null || b == null) return a === b;
5+
if (typeof a !== typeof b) return false;
6+
if (typeof a !== 'object') return a === b;
7+
if (Array.isArray(a) !== Array.isArray(b)) return false;
8+
if (Array.isArray(a))
9+
return a.length === b.length && a.every((value, index) => deepEqual(value, b[index]));
10+
const keysA = Object.keys(a);
11+
const keysB = Object.keys(b);
12+
if (keysA.length !== keysB.length) return false;
13+
for (const key of keysA) {
14+
if (!keysB.includes(key)) return false;
15+
if (!deepEqual(a[key], b[key])) return false;
16+
}
17+
return true;
18+
};
19+
/**
20+
* @name useShallowEffect
21+
* @description - Hook that executes an effect only when dependencies change shallowly or deeply.
22+
* @category Lifecycle
23+
*
24+
* @param {EffectCallback} effect The effect callback
25+
* @param {DependencyList} [deps] The dependencies list for the effect
26+
*
27+
* @example
28+
* useShallowEffect(() => console.log("effect"), [user]);
29+
*/
30+
export const useShallowEffect = (effect, deps) => {
31+
const depsRef = useRef(deps);
32+
if (!depsRef.current || !deepEqual(deps, depsRef.current)) {
33+
depsRef.current = deps;
34+
}
35+
useEffect(effect, depsRef.current);
36+
};

‎packages/core/src/bundle/hooks/useStorage/useStorage.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ export const dispatchStorageEvent = (params) =>
55
const setStorageItem = (storage, key, value) => {
66
const oldValue = storage.getItem(key);
77
storage.setItem(key, value);
8-
dispatchStorageEvent({ key, oldValue, newValue: value, storageArea: storage });
8+
dispatchStorageEvent({
9+
key,
10+
oldValue,
11+
newValue: value,
12+
storageArea: storage
13+
});
914
};
1015
const removeStorageItem = (storage, key) => {
1116
const oldValue = storage.getItem(key);

0 commit comments

Comments
 (0)