minimal-shared 0.0.2
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/README.md +3 -0
- package/dist/hooks/index.d.ts +20 -0
- package/dist/hooks/index.js +19 -0
- package/dist/hooks/use-back-to-top/index.d.ts +2 -0
- package/dist/hooks/use-back-to-top/index.js +1 -0
- package/dist/hooks/use-back-to-top/use-back-to-top.d.ts +33 -0
- package/dist/hooks/use-back-to-top/use-back-to-top.js +64 -0
- package/dist/hooks/use-boolean/index.d.ts +2 -0
- package/dist/hooks/use-boolean/index.js +1 -0
- package/dist/hooks/use-boolean/use-boolean.d.ts +29 -0
- package/dist/hooks/use-boolean/use-boolean.js +24 -0
- package/dist/hooks/use-client-rect/index.d.ts +2 -0
- package/dist/hooks/use-client-rect/index.js +1 -0
- package/dist/hooks/use-client-rect/use-client-rect.d.ts +29 -0
- package/dist/hooks/use-client-rect/use-client-rect.js +47 -0
- package/dist/hooks/use-cookies/index.d.ts +1 -0
- package/dist/hooks/use-cookies/index.js +1 -0
- package/dist/hooks/use-cookies/use-cookies.d.ts +39 -0
- package/dist/hooks/use-cookies/use-cookies.js +110 -0
- package/dist/hooks/use-copy-to-clipboard/index.d.ts +1 -0
- package/dist/hooks/use-copy-to-clipboard/index.js +1 -0
- package/dist/hooks/use-copy-to-clipboard/use-copy-to-clipboard.d.ts +26 -0
- package/dist/hooks/use-copy-to-clipboard/use-copy-to-clipboard.js +27 -0
- package/dist/hooks/use-countdown-date/index.d.ts +1 -0
- package/dist/hooks/use-countdown-date/index.js +1 -0
- package/dist/hooks/use-countdown-date/use-countdown-date.d.ts +29 -0
- package/dist/hooks/use-countdown-date/use-countdown-date.js +41 -0
- package/dist/hooks/use-countdown-seconds/index.d.ts +2 -0
- package/dist/hooks/use-countdown-seconds/index.js +1 -0
- package/dist/hooks/use-countdown-seconds/use-countdown-seconds.d.ts +35 -0
- package/dist/hooks/use-countdown-seconds/use-countdown-seconds.js +36 -0
- package/dist/hooks/use-debounce/index.d.ts +1 -0
- package/dist/hooks/use-debounce/index.js +1 -0
- package/dist/hooks/use-debounce/use-debounce.d.ts +21 -0
- package/dist/hooks/use-debounce/use-debounce.js +17 -0
- package/dist/hooks/use-double-click/index.d.ts +2 -0
- package/dist/hooks/use-double-click/index.js +1 -0
- package/dist/hooks/use-double-click/use-double-click.d.ts +28 -0
- package/dist/hooks/use-double-click/use-double-click.js +33 -0
- package/dist/hooks/use-event-listener/index.d.ts +2 -0
- package/dist/hooks/use-event-listener/index.js +1 -0
- package/dist/hooks/use-event-listener/use-event-listener.d.ts +7 -0
- package/dist/hooks/use-event-listener/use-event-listener.js +23 -0
- package/dist/hooks/use-is-client/index.d.ts +1 -0
- package/dist/hooks/use-is-client/index.js +1 -0
- package/dist/hooks/use-is-client/use-is-client.d.ts +18 -0
- package/dist/hooks/use-is-client/use-is-client.js +12 -0
- package/dist/hooks/use-local-storage/index.d.ts +1 -0
- package/dist/hooks/use-local-storage/index.js +1 -0
- package/dist/hooks/use-local-storage/use-local-storage.d.ts +37 -0
- package/dist/hooks/use-local-storage/use-local-storage.js +113 -0
- package/dist/hooks/use-multi-select/index.d.ts +2 -0
- package/dist/hooks/use-multi-select/index.js +1 -0
- package/dist/hooks/use-multi-select/use-multi-select.d.ts +55 -0
- package/dist/hooks/use-multi-select/use-multi-select.js +36 -0
- package/dist/hooks/use-popover/index.d.ts +2 -0
- package/dist/hooks/use-popover/index.js +1 -0
- package/dist/hooks/use-popover/use-popover.d.ts +35 -0
- package/dist/hooks/use-popover/use-popover.js +21 -0
- package/dist/hooks/use-popover-hover/index.d.ts +2 -0
- package/dist/hooks/use-popover-hover/index.js +1 -0
- package/dist/hooks/use-popover-hover/use-popover-hover.d.ts +41 -0
- package/dist/hooks/use-popover-hover/use-popover-hover.js +24 -0
- package/dist/hooks/use-scroll-offset-top/index.d.ts +2 -0
- package/dist/hooks/use-scroll-offset-top/index.js +1 -0
- package/dist/hooks/use-scroll-offset-top/use-scroll-offset-top.d.ts +28 -0
- package/dist/hooks/use-scroll-offset-top/use-scroll-offset-top.js +29 -0
- package/dist/hooks/use-set-state/index.d.ts +1 -0
- package/dist/hooks/use-set-state/index.js +1 -0
- package/dist/hooks/use-set-state/use-set-state.d.ts +32 -0
- package/dist/hooks/use-set-state/use-set-state.js +26 -0
- package/dist/hooks/use-tabs/index.d.ts +2 -0
- package/dist/hooks/use-tabs/index.js +1 -0
- package/dist/hooks/use-tabs/use-tabs.d.ts +30 -0
- package/dist/hooks/use-tabs/use-tabs.js +16 -0
- package/dist/hooks/use-text-input/index.d.ts +2 -0
- package/dist/hooks/use-text-input/index.js +1 -0
- package/dist/hooks/use-text-input/use-text-input.d.ts +16 -0
- package/dist/hooks/use-text-input/use-text-input.js +16 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +2 -0
- package/dist/utils/active-link/active-link.d.ts +16 -0
- package/dist/utils/active-link/active-link.js +43 -0
- package/dist/utils/active-link/index.d.ts +1 -0
- package/dist/utils/active-link/index.js +1 -0
- package/dist/utils/classes/classes.d.ts +25 -0
- package/dist/utils/classes/classes.js +14 -0
- package/dist/utils/classes/index.d.ts +1 -0
- package/dist/utils/classes/index.js +1 -0
- package/dist/utils/color/color.d.ts +67 -0
- package/dist/utils/color/color.js +47 -0
- package/dist/utils/color/index.d.ts +1 -0
- package/dist/utils/color/index.js +1 -0
- package/dist/utils/cookies/cookies.d.ts +34 -0
- package/dist/utils/cookies/cookies.js +46 -0
- package/dist/utils/cookies/index.d.ts +1 -0
- package/dist/utils/cookies/index.js +1 -0
- package/dist/utils/font/font.d.ts +37 -0
- package/dist/utils/font/font.js +20 -0
- package/dist/utils/font/index.d.ts +1 -0
- package/dist/utils/font/index.js +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.js +17 -0
- package/dist/utils/local-storage/index.d.ts +1 -0
- package/dist/utils/local-storage/index.js +1 -0
- package/dist/utils/local-storage/local-storage.d.ts +55 -0
- package/dist/utils/local-storage/local-storage.js +51 -0
- package/dist/utils/object/index.d.ts +1 -0
- package/dist/utils/object/index.js +1 -0
- package/dist/utils/object/object.d.ts +26 -0
- package/dist/utils/object/object.js +10 -0
- package/dist/utils/url/index.d.ts +1 -0
- package/dist/utils/url/index.js +1 -0
- package/dist/utils/url/url.d.ts +46 -0
- package/dist/utils/url/url.js +28 -0
- package/dist/utils/uuidv4/index.d.ts +1 -0
- package/dist/utils/uuidv4/index.js +1 -0
- package/dist/utils/uuidv4/uuidv4.d.ts +12 -0
- package/dist/utils/uuidv4/uuidv4.js +11 -0
- package/package.json +87 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/hooks/use-countdown-seconds/use-countdown-seconds.ts
|
|
2
|
+
import { useState, useEffect, useCallback } from "react";
|
|
3
|
+
function useCountdownSeconds(defaultValue) {
|
|
4
|
+
const [value, setValue] = useState(defaultValue);
|
|
5
|
+
const [isCounting, setIsCounting] = useState(false);
|
|
6
|
+
const handleStart = useCallback(() => {
|
|
7
|
+
setIsCounting(true);
|
|
8
|
+
}, []);
|
|
9
|
+
const handleReset = useCallback(() => {
|
|
10
|
+
setIsCounting(false);
|
|
11
|
+
setValue(defaultValue);
|
|
12
|
+
}, [defaultValue]);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
let interval = null;
|
|
15
|
+
if (isCounting && value > 0) {
|
|
16
|
+
interval = setInterval(() => {
|
|
17
|
+
setValue((prevValue) => prevValue - 1);
|
|
18
|
+
}, 1e3);
|
|
19
|
+
} else if (value <= 0) {
|
|
20
|
+
setIsCounting(false);
|
|
21
|
+
}
|
|
22
|
+
return () => {
|
|
23
|
+
if (interval) clearInterval(interval);
|
|
24
|
+
};
|
|
25
|
+
}, [isCounting, value]);
|
|
26
|
+
return {
|
|
27
|
+
value,
|
|
28
|
+
setValue,
|
|
29
|
+
isCounting,
|
|
30
|
+
start: handleStart,
|
|
31
|
+
reset: handleReset
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
useCountdownSeconds
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { UseDebounceReturn, useDebounce } from './use-debounce.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-debounce';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook to debounce a value. The debounced value will only update after the specified delay has passed without any changes.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} value - The value to debounce.
|
|
5
|
+
* @param {number} [delay=1000] - The delay in milliseconds to wait before updating the debounced value.
|
|
6
|
+
*
|
|
7
|
+
* @returns {UseDebounceReturn} - The debounced value.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
|
11
|
+
*
|
|
12
|
+
* useEffect(() => {
|
|
13
|
+
* if (debouncedSearchTerm) {
|
|
14
|
+
* // Perform search
|
|
15
|
+
* }
|
|
16
|
+
* }, [debouncedSearchTerm]);
|
|
17
|
+
*/
|
|
18
|
+
type UseDebounceReturn = string;
|
|
19
|
+
declare function useDebounce(value: string, delay?: number): UseDebounceReturn;
|
|
20
|
+
|
|
21
|
+
export { type UseDebounceReturn, useDebounce };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/hooks/use-debounce/use-debounce.ts
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
function useDebounce(value, delay = 1e3) {
|
|
4
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const handler = setTimeout(() => {
|
|
7
|
+
setDebouncedValue(value);
|
|
8
|
+
}, delay);
|
|
9
|
+
return () => {
|
|
10
|
+
clearTimeout(handler);
|
|
11
|
+
};
|
|
12
|
+
}, [value, delay]);
|
|
13
|
+
return debouncedValue;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
useDebounce
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-double-click';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MouseEvent, SyntheticEvent } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to handle single and double click events on an element.
|
|
5
|
+
*
|
|
6
|
+
* @param {UseDoubleClickProps} props - The properties for the hook.
|
|
7
|
+
* @param {number} [props.timeout=250] - The timeout in milliseconds to differentiate between single and double clicks.
|
|
8
|
+
* @param {function} [props.click] - The function to call on a single click.
|
|
9
|
+
* @param {function} props.doubleClick - The function to call on a double click.
|
|
10
|
+
*
|
|
11
|
+
* @returns {UseDoubleClickReturn} - A function to handle the click events.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const handleClick = (event) => console.log('Single Click', event);
|
|
15
|
+
* const handleDoubleClick = (event) => console.log('Double Click', event);
|
|
16
|
+
* const handleEvent = useDoubleClick({ click: handleClick, doubleClick: handleDoubleClick });
|
|
17
|
+
*
|
|
18
|
+
* return <div onClick={handleEvent}>Click Me</div>;
|
|
19
|
+
*/
|
|
20
|
+
type UseDoubleClickReturn = (event: MouseEvent<HTMLElement>) => void;
|
|
21
|
+
type UseDoubleClickProps = {
|
|
22
|
+
timeout?: number;
|
|
23
|
+
click?: (event: SyntheticEvent) => void;
|
|
24
|
+
doubleClick: (event: SyntheticEvent) => void;
|
|
25
|
+
};
|
|
26
|
+
declare function useDoubleClick({ click, doubleClick, timeout, }: UseDoubleClickProps): UseDoubleClickReturn;
|
|
27
|
+
|
|
28
|
+
export { type UseDoubleClickReturn, useDoubleClick };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/hooks/use-double-click/use-double-click.ts
|
|
2
|
+
import { useRef, useCallback } from "react";
|
|
3
|
+
function useDoubleClick({
|
|
4
|
+
click,
|
|
5
|
+
doubleClick,
|
|
6
|
+
timeout = 250
|
|
7
|
+
}) {
|
|
8
|
+
const clickTimeout = useRef(null);
|
|
9
|
+
const clearClickTimeout = useCallback(() => {
|
|
10
|
+
if (clickTimeout.current) {
|
|
11
|
+
clearTimeout(clickTimeout.current);
|
|
12
|
+
clickTimeout.current = null;
|
|
13
|
+
}
|
|
14
|
+
}, []);
|
|
15
|
+
const handleEvent = useCallback(
|
|
16
|
+
(event) => {
|
|
17
|
+
clearClickTimeout();
|
|
18
|
+
if (click && event.detail === 1) {
|
|
19
|
+
clickTimeout.current = setTimeout(() => {
|
|
20
|
+
click(event);
|
|
21
|
+
}, timeout);
|
|
22
|
+
}
|
|
23
|
+
if (event.detail % 2 === 0) {
|
|
24
|
+
doubleClick(event);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
[click, doubleClick, timeout, clearClickTimeout]
|
|
28
|
+
);
|
|
29
|
+
return handleEvent;
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
useDoubleClick
|
|
33
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-event-listener';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (event: WindowEventMap[K]) => void, element?: undefined, options?: boolean | AddEventListenerOptions): void;
|
|
4
|
+
declare function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = HTMLDivElement>(eventName: K, handler: (event: HTMLElementEventMap[K]) => void, element: RefObject<T>, options?: boolean | AddEventListenerOptions): void;
|
|
5
|
+
declare function useEventListener<K extends keyof DocumentEventMap>(eventName: K, handler: (event: DocumentEventMap[K]) => void, element: RefObject<Document>, options?: boolean | AddEventListenerOptions): void;
|
|
6
|
+
|
|
7
|
+
export { useEventListener };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/hooks/use-event-listener/use-event-listener.ts
|
|
2
|
+
import { useRef, useEffect, useLayoutEffect } from "react";
|
|
3
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
4
|
+
function useEventListener(eventName, handler, element, options) {
|
|
5
|
+
const savedHandler = useRef(handler);
|
|
6
|
+
useIsomorphicLayoutEffect(() => {
|
|
7
|
+
savedHandler.current = handler;
|
|
8
|
+
}, [handler]);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const targetElement = element?.current || window;
|
|
11
|
+
if (!(targetElement && targetElement.addEventListener)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const eventListener = (event) => savedHandler.current(event);
|
|
15
|
+
targetElement.addEventListener(eventName, eventListener, options);
|
|
16
|
+
return () => {
|
|
17
|
+
targetElement.removeEventListener(eventName, eventListener);
|
|
18
|
+
};
|
|
19
|
+
}, [eventName, element, options]);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
useEventListener
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { UseIsClientReturn, useIsClient } from './use-is-client.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-is-client';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook to determine if the code is running on the client side.
|
|
3
|
+
*
|
|
4
|
+
* @returns {boolean} - Returns true if the code is running on the client side, otherwise false.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const isClient = useIsClient();
|
|
8
|
+
*
|
|
9
|
+
* return (
|
|
10
|
+
* <div>
|
|
11
|
+
* <p>Is Client: {isClient.toString()}</p>
|
|
12
|
+
* </div>
|
|
13
|
+
* );
|
|
14
|
+
*/
|
|
15
|
+
type UseIsClientReturn = boolean;
|
|
16
|
+
declare function useIsClient(): UseIsClientReturn;
|
|
17
|
+
|
|
18
|
+
export { type UseIsClientReturn, useIsClient };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/hooks/use-is-client/use-is-client.ts
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
function useIsClient() {
|
|
4
|
+
const [isClient, setClient] = useState(false);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
setClient(true);
|
|
7
|
+
}, []);
|
|
8
|
+
return isClient;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
useIsClient
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { UseLocalStorageReturn, useLocalStorage } from './use-local-storage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-local-storage';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook to manage state with local storage.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} key - The key for the local storage.
|
|
5
|
+
* @param {T} initialState - The initial state value.
|
|
6
|
+
* @param {Object} [options] - Optional settings.
|
|
7
|
+
* @param {boolean} [options.initOnLoad=false] - Whether to initialize the local storage on load.
|
|
8
|
+
*
|
|
9
|
+
* @returns {UseLocalStorageReturn<T>} - An object containing:
|
|
10
|
+
* - `state`: The current state.
|
|
11
|
+
* - `resetState`: A function to reset the state to the initial value and remove it from local storage.
|
|
12
|
+
* - `updateState`: A function to update the state and save it to local storage.
|
|
13
|
+
* - `updateField`: A function to update a specific field in the state and save it to local storage.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const { state, resetState, updateState, updateField } = useLocalStorage('settings', initialState);
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <div>
|
|
20
|
+
* <p>State: {JSON.stringify(state)}</p>
|
|
21
|
+
* <button onClick={() => updateState({name: 'John', age: 20})}>Set Name</button>
|
|
22
|
+
* <button onClick={() => updateField('name', 'John')}>Set Name</button>
|
|
23
|
+
* <button onClick={resetState}>Reset</button>
|
|
24
|
+
* </div>
|
|
25
|
+
* );
|
|
26
|
+
*/
|
|
27
|
+
type UseLocalStorageReturn<T> = {
|
|
28
|
+
state: T;
|
|
29
|
+
resetState: (defaultState?: T) => void;
|
|
30
|
+
setState: (updateState: T | Partial<T>) => void;
|
|
31
|
+
setField: (name: keyof T, updateValue: T[keyof T]) => void;
|
|
32
|
+
};
|
|
33
|
+
declare function useLocalStorage<T>(key: string, initialState?: T, options?: {
|
|
34
|
+
initOnLoad?: boolean;
|
|
35
|
+
}): UseLocalStorageReturn<T>;
|
|
36
|
+
|
|
37
|
+
export { type UseLocalStorageReturn, useLocalStorage };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// src/hooks/use-local-storage/use-local-storage.ts
|
|
2
|
+
import { useMemo, useState, useEffect, useCallback } from "react";
|
|
3
|
+
|
|
4
|
+
// src/utils/local-storage/local-storage.ts
|
|
5
|
+
function getStorage(key) {
|
|
6
|
+
const storedValue = localStorageGetItem(key);
|
|
7
|
+
if (storedValue) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(storedValue);
|
|
10
|
+
} catch {
|
|
11
|
+
return storedValue;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function setStorage(key, value) {
|
|
17
|
+
try {
|
|
18
|
+
const serializedValue = JSON.stringify(value);
|
|
19
|
+
window.localStorage.setItem(key, serializedValue);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error("Error while setting storage:", error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function removeStorage(key) {
|
|
25
|
+
try {
|
|
26
|
+
window.localStorage.removeItem(key);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error("Error while removing from storage:", error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function localStorageAvailable() {
|
|
32
|
+
try {
|
|
33
|
+
const key = "__some_random_key_you_are_not_going_to_use__";
|
|
34
|
+
window.localStorage.setItem(key, key);
|
|
35
|
+
window.localStorage.removeItem(key);
|
|
36
|
+
return true;
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function localStorageGetItem(key, defaultValue = "") {
|
|
42
|
+
if (!localStorageAvailable()) {
|
|
43
|
+
return defaultValue;
|
|
44
|
+
}
|
|
45
|
+
const value = localStorage.getItem(key);
|
|
46
|
+
return value ?? defaultValue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/hooks/use-local-storage/use-local-storage.ts
|
|
50
|
+
function useLocalStorage(key, initialState, options) {
|
|
51
|
+
const isValuePresent = !!getStorage(key);
|
|
52
|
+
const storedValue = getStorage(key) ?? initialState;
|
|
53
|
+
const [state, set] = useState(storedValue);
|
|
54
|
+
const { initOnLoad = true } = options ?? {};
|
|
55
|
+
const hasMultipleValues = state && typeof state === "object";
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (storedValue) {
|
|
58
|
+
if (hasMultipleValues) {
|
|
59
|
+
set((prevValue) => ({ ...prevValue, ...storedValue }));
|
|
60
|
+
} else {
|
|
61
|
+
set(storedValue);
|
|
62
|
+
}
|
|
63
|
+
if (!isValuePresent && initOnLoad) {
|
|
64
|
+
setStorage(key, storedValue);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}, []);
|
|
68
|
+
const setState = useCallback(
|
|
69
|
+
(newState) => {
|
|
70
|
+
if (hasMultipleValues) {
|
|
71
|
+
set((prevValue) => {
|
|
72
|
+
const updatedState = { ...prevValue, ...newState };
|
|
73
|
+
setStorage(key, updatedState);
|
|
74
|
+
return updatedState;
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
setStorage(key, newState);
|
|
78
|
+
set(newState);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[key, hasMultipleValues]
|
|
82
|
+
);
|
|
83
|
+
const setField = useCallback(
|
|
84
|
+
(name, updateValue) => {
|
|
85
|
+
if (hasMultipleValues) {
|
|
86
|
+
setState({ [name]: updateValue });
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
[hasMultipleValues, setState]
|
|
90
|
+
);
|
|
91
|
+
const resetState = useCallback(
|
|
92
|
+
(defaultState) => {
|
|
93
|
+
if (defaultState) {
|
|
94
|
+
set(defaultState);
|
|
95
|
+
}
|
|
96
|
+
removeStorage(key);
|
|
97
|
+
},
|
|
98
|
+
[key]
|
|
99
|
+
);
|
|
100
|
+
const memoizedValue = useMemo(
|
|
101
|
+
() => ({
|
|
102
|
+
state,
|
|
103
|
+
setState,
|
|
104
|
+
setField,
|
|
105
|
+
resetState
|
|
106
|
+
}),
|
|
107
|
+
[resetState, setField, setState, state]
|
|
108
|
+
);
|
|
109
|
+
return memoizedValue;
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
useLocalStorage
|
|
113
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-multi-select';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to manage the selection state of a list of items.
|
|
5
|
+
*
|
|
6
|
+
* @param {string[]} itemIds - The list of item IDs to manage.
|
|
7
|
+
* @param {string[]} [defaultSelected=[]] - The list of default selected item IDs.
|
|
8
|
+
*
|
|
9
|
+
* @returns {UseMultiSelectReturn} - An object containing:
|
|
10
|
+
* - `values`: The current list of selected item IDs.
|
|
11
|
+
* - `status`: The current selection status ('checked', 'unchecked', 'indeterminate').
|
|
12
|
+
* - `setValues`: A function to manually set the selected item IDs.
|
|
13
|
+
* - `onSelectAllItems`: A function to select all items.
|
|
14
|
+
* - `onDeSelectAllItems`: A function to deselect all items.
|
|
15
|
+
* - `onToggleSelectItem`: A function to toggle the selection of a specific item.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const { values, status, onSelectAllItems, onDeSelectAllItems, onToggleSelectItem } = useMultiSelect(['item1', 'item2', 'item3'], ['item1']);
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <div>
|
|
22
|
+
* <button onClick={onSelectAllItems}>Select All</button>
|
|
23
|
+
* <button onClick={onDeSelectAllItems}>Deselect All</button>
|
|
24
|
+
* {itemIds.map(itemId => (
|
|
25
|
+
* <div key={itemId}>
|
|
26
|
+
* <input
|
|
27
|
+
* type="checkbox"
|
|
28
|
+
* checked={values.includes(itemId)}
|
|
29
|
+
* onChange={() => onToggleSelectItem(itemId)}
|
|
30
|
+
* />
|
|
31
|
+
* {itemId}
|
|
32
|
+
* </div>
|
|
33
|
+
* ))}
|
|
34
|
+
* </div>
|
|
35
|
+
* );
|
|
36
|
+
*/
|
|
37
|
+
type UseMultiSelectReturn = {
|
|
38
|
+
values: string[];
|
|
39
|
+
status: 'checked' | 'unchecked' | 'indeterminate';
|
|
40
|
+
setValues: Dispatch<SetStateAction<string[]>>;
|
|
41
|
+
onSelectAllItems: () => void;
|
|
42
|
+
onDeSelectAllItems: () => void;
|
|
43
|
+
onToggleSelectItem: (inputValue: string) => void;
|
|
44
|
+
};
|
|
45
|
+
declare function useMultiSelect(listItems: string[], defaultSelectedItems?: string[]): UseMultiSelectReturn;
|
|
46
|
+
/**
|
|
47
|
+
* Updates the selected items list by adding or removing the specified item.
|
|
48
|
+
*
|
|
49
|
+
* @param {string[]} selectedItems - The current list of selected items.
|
|
50
|
+
* @param {string} newItem - The item to add or remove.
|
|
51
|
+
* @returns {string[]} - The updated list of selected items.
|
|
52
|
+
*/
|
|
53
|
+
declare function updateSelectedItems(selectedItems: string[], newItem: string): string[];
|
|
54
|
+
|
|
55
|
+
export { type UseMultiSelectReturn, updateSelectedItems, useMultiSelect };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/hooks/use-multi-select/use-multi-select.ts
|
|
2
|
+
import { useMemo, useState, useCallback } from "react";
|
|
3
|
+
function useMultiSelect(listItems, defaultSelectedItems) {
|
|
4
|
+
const [values, setValues] = useState(defaultSelectedItems ?? []);
|
|
5
|
+
const onToggleSelectItem = useCallback((newItem) => {
|
|
6
|
+
setValues((prevSelectedItems) => updateSelectedItems(prevSelectedItems, newItem));
|
|
7
|
+
}, []);
|
|
8
|
+
const onSelectAllItems = useCallback(() => {
|
|
9
|
+
setValues(
|
|
10
|
+
(prevSelectedItems) => prevSelectedItems.length === listItems.length ? [] : listItems
|
|
11
|
+
);
|
|
12
|
+
}, [listItems]);
|
|
13
|
+
const onDeSelectAllItems = useCallback(() => {
|
|
14
|
+
setValues([]);
|
|
15
|
+
}, []);
|
|
16
|
+
const status = useMemo(() => {
|
|
17
|
+
if (values.length === 0) return "unchecked";
|
|
18
|
+
if (values.length === listItems.length) return "checked";
|
|
19
|
+
return "indeterminate";
|
|
20
|
+
}, [listItems.length, values.length]);
|
|
21
|
+
return {
|
|
22
|
+
values,
|
|
23
|
+
status,
|
|
24
|
+
setValues,
|
|
25
|
+
onSelectAllItems,
|
|
26
|
+
onDeSelectAllItems,
|
|
27
|
+
onToggleSelectItem
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function updateSelectedItems(selectedItems, newItem) {
|
|
31
|
+
return selectedItems.includes(newItem) ? selectedItems.filter((existingItem) => existingItem !== newItem) : [...selectedItems, newItem];
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
updateSelectedItems,
|
|
35
|
+
useMultiSelect
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-popover';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MouseEvent, Dispatch, SetStateAction } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to manage the state of a popover.
|
|
5
|
+
*
|
|
6
|
+
* @returns {UsePopoverReturn<T>} - An object containing:
|
|
7
|
+
* - `open`: A boolean indicating whether the popover is open.
|
|
8
|
+
* - `anchorEl`: The current element that the popover is anchored to.
|
|
9
|
+
* - `onClose`: A function to close the popover.
|
|
10
|
+
* - `onOpen`: A function to open the popover.
|
|
11
|
+
* - `setAnchorEl`: A function to manually set the anchor element.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const { open, anchorEl, onOpen, onClose } = usePopover<HTMLButtonElement>();
|
|
15
|
+
*
|
|
16
|
+
* return (
|
|
17
|
+
* <>
|
|
18
|
+
* <button variant="contained" onClick={onOpen}>Click me</button>
|
|
19
|
+
*
|
|
20
|
+
* <Popover open={open} onClose={onClose} anchorEl={anchorEl}>
|
|
21
|
+
* Popover content
|
|
22
|
+
* </Popover>
|
|
23
|
+
* </>
|
|
24
|
+
* );
|
|
25
|
+
*/
|
|
26
|
+
type UsePopoverReturn<T> = {
|
|
27
|
+
open: boolean;
|
|
28
|
+
anchorEl: T | null;
|
|
29
|
+
onClose: () => void;
|
|
30
|
+
onOpen: (event: MouseEvent<HTMLElement>) => void;
|
|
31
|
+
setAnchorEl: Dispatch<SetStateAction<T | null>>;
|
|
32
|
+
};
|
|
33
|
+
declare function usePopover<T extends HTMLElement>(): UsePopoverReturn<T>;
|
|
34
|
+
|
|
35
|
+
export { type UsePopoverReturn, usePopover };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/hooks/use-popover/use-popover.ts
|
|
2
|
+
import { useState, useCallback } from "react";
|
|
3
|
+
function usePopover() {
|
|
4
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
5
|
+
const onOpen = useCallback((event) => {
|
|
6
|
+
setAnchorEl(event.currentTarget);
|
|
7
|
+
}, []);
|
|
8
|
+
const onClose = useCallback(() => {
|
|
9
|
+
setAnchorEl(null);
|
|
10
|
+
}, []);
|
|
11
|
+
return {
|
|
12
|
+
open: !!anchorEl,
|
|
13
|
+
anchorEl,
|
|
14
|
+
onOpen,
|
|
15
|
+
onClose,
|
|
16
|
+
setAnchorEl
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
usePopover
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-popover-hover';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RefObject, Dispatch, SetStateAction } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to manage the state of a popover that opens on hover.
|
|
5
|
+
*
|
|
6
|
+
* @param {RefObject<T>} [inputRef] - An optional ref object to use for the popover element.
|
|
7
|
+
*
|
|
8
|
+
* @returns {UsePopoverHoverReturn<T>} - An object containing:
|
|
9
|
+
* - `open`: A boolean indicating whether the popover is open.
|
|
10
|
+
* - `onOpen`: A function to open the popover.
|
|
11
|
+
* - `anchorEl`: The current element that the popover is anchored to.
|
|
12
|
+
* - `onClose`: A function to close the popover.
|
|
13
|
+
* - `elementRef`: A ref object for the popover element.
|
|
14
|
+
* - `setOpen`: A function to manually set the open state of the popover.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const { open, onOpen, onClose, elementRef } = usePopoverHover<HTMLButtonElement>();
|
|
18
|
+
*
|
|
19
|
+
* return (
|
|
20
|
+
* <>
|
|
21
|
+
* <button ref={elementRef} onMouseEnter={onOpen} onMouseLeave={onClose}>
|
|
22
|
+
* Hover me
|
|
23
|
+
* </button>
|
|
24
|
+
*
|
|
25
|
+
* <Popover open={open} anchorEl={anchorEl}>
|
|
26
|
+
* Popover content
|
|
27
|
+
* </Popover>
|
|
28
|
+
* </>
|
|
29
|
+
* );
|
|
30
|
+
*/
|
|
31
|
+
type UsePopoverHoverReturn<T> = {
|
|
32
|
+
open: boolean;
|
|
33
|
+
onOpen: () => void;
|
|
34
|
+
anchorEl: T | null;
|
|
35
|
+
onClose: () => void;
|
|
36
|
+
elementRef: RefObject<T>;
|
|
37
|
+
setOpen: Dispatch<SetStateAction<boolean>>;
|
|
38
|
+
};
|
|
39
|
+
declare function usePopoverHover<T extends HTMLElement>(inputRef?: RefObject<T>): UsePopoverHoverReturn<T>;
|
|
40
|
+
|
|
41
|
+
export { usePopoverHover };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/hooks/use-popover-hover/use-popover-hover.ts
|
|
2
|
+
import { useRef, useState, useCallback } from "react";
|
|
3
|
+
function usePopoverHover(inputRef) {
|
|
4
|
+
const initialRef = useRef(null);
|
|
5
|
+
const elementRef = inputRef || initialRef;
|
|
6
|
+
const [open, setOpen] = useState(false);
|
|
7
|
+
const onOpen = useCallback(() => {
|
|
8
|
+
setOpen(true);
|
|
9
|
+
}, []);
|
|
10
|
+
const onClose = useCallback(() => {
|
|
11
|
+
setOpen(false);
|
|
12
|
+
}, []);
|
|
13
|
+
return {
|
|
14
|
+
elementRef,
|
|
15
|
+
anchorEl: elementRef.current,
|
|
16
|
+
open,
|
|
17
|
+
onOpen,
|
|
18
|
+
onClose,
|
|
19
|
+
setOpen
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
usePopoverHover
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-scroll-offset-top';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to manage the offset top state based on scroll position.
|
|
5
|
+
*
|
|
6
|
+
* @param {number} [defaultValue=0] - The offset value at which the state changes.
|
|
7
|
+
*
|
|
8
|
+
* @returns {UseScrollOffsetTopReturn<T>} - An object containing:
|
|
9
|
+
* - `offsetTop`: A boolean indicating whether the scroll position is past the offset.
|
|
10
|
+
* - `elementRef`: A ref object to attach to the element to track its offset.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* 1.Applies to top <header/>
|
|
14
|
+
* const { offsetTop } = useScrollOffsetTop(80);
|
|
15
|
+
*
|
|
16
|
+
* Or
|
|
17
|
+
*
|
|
18
|
+
* 2.Applies to element
|
|
19
|
+
* const { offsetTop, elementRef } = useScrollOffsetTop(80);
|
|
20
|
+
* <div ref={elementRef} />
|
|
21
|
+
*/
|
|
22
|
+
type UseScrollOffsetTopReturn<T> = {
|
|
23
|
+
offsetTop: boolean;
|
|
24
|
+
elementRef: RefObject<T>;
|
|
25
|
+
};
|
|
26
|
+
declare function useScrollOffsetTop<T extends HTMLElement>(defaultValue?: number): UseScrollOffsetTopReturn<T>;
|
|
27
|
+
|
|
28
|
+
export { type UseScrollOffsetTopReturn, useScrollOffsetTop };
|