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.
Files changed (120) hide show
  1. package/README.md +3 -0
  2. package/dist/hooks/index.d.ts +20 -0
  3. package/dist/hooks/index.js +19 -0
  4. package/dist/hooks/use-back-to-top/index.d.ts +2 -0
  5. package/dist/hooks/use-back-to-top/index.js +1 -0
  6. package/dist/hooks/use-back-to-top/use-back-to-top.d.ts +33 -0
  7. package/dist/hooks/use-back-to-top/use-back-to-top.js +64 -0
  8. package/dist/hooks/use-boolean/index.d.ts +2 -0
  9. package/dist/hooks/use-boolean/index.js +1 -0
  10. package/dist/hooks/use-boolean/use-boolean.d.ts +29 -0
  11. package/dist/hooks/use-boolean/use-boolean.js +24 -0
  12. package/dist/hooks/use-client-rect/index.d.ts +2 -0
  13. package/dist/hooks/use-client-rect/index.js +1 -0
  14. package/dist/hooks/use-client-rect/use-client-rect.d.ts +29 -0
  15. package/dist/hooks/use-client-rect/use-client-rect.js +47 -0
  16. package/dist/hooks/use-cookies/index.d.ts +1 -0
  17. package/dist/hooks/use-cookies/index.js +1 -0
  18. package/dist/hooks/use-cookies/use-cookies.d.ts +39 -0
  19. package/dist/hooks/use-cookies/use-cookies.js +110 -0
  20. package/dist/hooks/use-copy-to-clipboard/index.d.ts +1 -0
  21. package/dist/hooks/use-copy-to-clipboard/index.js +1 -0
  22. package/dist/hooks/use-copy-to-clipboard/use-copy-to-clipboard.d.ts +26 -0
  23. package/dist/hooks/use-copy-to-clipboard/use-copy-to-clipboard.js +27 -0
  24. package/dist/hooks/use-countdown-date/index.d.ts +1 -0
  25. package/dist/hooks/use-countdown-date/index.js +1 -0
  26. package/dist/hooks/use-countdown-date/use-countdown-date.d.ts +29 -0
  27. package/dist/hooks/use-countdown-date/use-countdown-date.js +41 -0
  28. package/dist/hooks/use-countdown-seconds/index.d.ts +2 -0
  29. package/dist/hooks/use-countdown-seconds/index.js +1 -0
  30. package/dist/hooks/use-countdown-seconds/use-countdown-seconds.d.ts +35 -0
  31. package/dist/hooks/use-countdown-seconds/use-countdown-seconds.js +36 -0
  32. package/dist/hooks/use-debounce/index.d.ts +1 -0
  33. package/dist/hooks/use-debounce/index.js +1 -0
  34. package/dist/hooks/use-debounce/use-debounce.d.ts +21 -0
  35. package/dist/hooks/use-debounce/use-debounce.js +17 -0
  36. package/dist/hooks/use-double-click/index.d.ts +2 -0
  37. package/dist/hooks/use-double-click/index.js +1 -0
  38. package/dist/hooks/use-double-click/use-double-click.d.ts +28 -0
  39. package/dist/hooks/use-double-click/use-double-click.js +33 -0
  40. package/dist/hooks/use-event-listener/index.d.ts +2 -0
  41. package/dist/hooks/use-event-listener/index.js +1 -0
  42. package/dist/hooks/use-event-listener/use-event-listener.d.ts +7 -0
  43. package/dist/hooks/use-event-listener/use-event-listener.js +23 -0
  44. package/dist/hooks/use-is-client/index.d.ts +1 -0
  45. package/dist/hooks/use-is-client/index.js +1 -0
  46. package/dist/hooks/use-is-client/use-is-client.d.ts +18 -0
  47. package/dist/hooks/use-is-client/use-is-client.js +12 -0
  48. package/dist/hooks/use-local-storage/index.d.ts +1 -0
  49. package/dist/hooks/use-local-storage/index.js +1 -0
  50. package/dist/hooks/use-local-storage/use-local-storage.d.ts +37 -0
  51. package/dist/hooks/use-local-storage/use-local-storage.js +113 -0
  52. package/dist/hooks/use-multi-select/index.d.ts +2 -0
  53. package/dist/hooks/use-multi-select/index.js +1 -0
  54. package/dist/hooks/use-multi-select/use-multi-select.d.ts +55 -0
  55. package/dist/hooks/use-multi-select/use-multi-select.js +36 -0
  56. package/dist/hooks/use-popover/index.d.ts +2 -0
  57. package/dist/hooks/use-popover/index.js +1 -0
  58. package/dist/hooks/use-popover/use-popover.d.ts +35 -0
  59. package/dist/hooks/use-popover/use-popover.js +21 -0
  60. package/dist/hooks/use-popover-hover/index.d.ts +2 -0
  61. package/dist/hooks/use-popover-hover/index.js +1 -0
  62. package/dist/hooks/use-popover-hover/use-popover-hover.d.ts +41 -0
  63. package/dist/hooks/use-popover-hover/use-popover-hover.js +24 -0
  64. package/dist/hooks/use-scroll-offset-top/index.d.ts +2 -0
  65. package/dist/hooks/use-scroll-offset-top/index.js +1 -0
  66. package/dist/hooks/use-scroll-offset-top/use-scroll-offset-top.d.ts +28 -0
  67. package/dist/hooks/use-scroll-offset-top/use-scroll-offset-top.js +29 -0
  68. package/dist/hooks/use-set-state/index.d.ts +1 -0
  69. package/dist/hooks/use-set-state/index.js +1 -0
  70. package/dist/hooks/use-set-state/use-set-state.d.ts +32 -0
  71. package/dist/hooks/use-set-state/use-set-state.js +26 -0
  72. package/dist/hooks/use-tabs/index.d.ts +2 -0
  73. package/dist/hooks/use-tabs/index.js +1 -0
  74. package/dist/hooks/use-tabs/use-tabs.d.ts +30 -0
  75. package/dist/hooks/use-tabs/use-tabs.js +16 -0
  76. package/dist/hooks/use-text-input/index.d.ts +2 -0
  77. package/dist/hooks/use-text-input/index.js +1 -0
  78. package/dist/hooks/use-text-input/use-text-input.d.ts +16 -0
  79. package/dist/hooks/use-text-input/use-text-input.js +16 -0
  80. package/dist/index.d.ts +29 -0
  81. package/dist/index.js +2 -0
  82. package/dist/utils/active-link/active-link.d.ts +16 -0
  83. package/dist/utils/active-link/active-link.js +43 -0
  84. package/dist/utils/active-link/index.d.ts +1 -0
  85. package/dist/utils/active-link/index.js +1 -0
  86. package/dist/utils/classes/classes.d.ts +25 -0
  87. package/dist/utils/classes/classes.js +14 -0
  88. package/dist/utils/classes/index.d.ts +1 -0
  89. package/dist/utils/classes/index.js +1 -0
  90. package/dist/utils/color/color.d.ts +67 -0
  91. package/dist/utils/color/color.js +47 -0
  92. package/dist/utils/color/index.d.ts +1 -0
  93. package/dist/utils/color/index.js +1 -0
  94. package/dist/utils/cookies/cookies.d.ts +34 -0
  95. package/dist/utils/cookies/cookies.js +46 -0
  96. package/dist/utils/cookies/index.d.ts +1 -0
  97. package/dist/utils/cookies/index.js +1 -0
  98. package/dist/utils/font/font.d.ts +37 -0
  99. package/dist/utils/font/font.js +20 -0
  100. package/dist/utils/font/index.d.ts +1 -0
  101. package/dist/utils/font/index.js +1 -0
  102. package/dist/utils/index.d.ts +9 -0
  103. package/dist/utils/index.js +17 -0
  104. package/dist/utils/local-storage/index.d.ts +1 -0
  105. package/dist/utils/local-storage/index.js +1 -0
  106. package/dist/utils/local-storage/local-storage.d.ts +55 -0
  107. package/dist/utils/local-storage/local-storage.js +51 -0
  108. package/dist/utils/object/index.d.ts +1 -0
  109. package/dist/utils/object/index.js +1 -0
  110. package/dist/utils/object/object.d.ts +26 -0
  111. package/dist/utils/object/object.js +10 -0
  112. package/dist/utils/url/index.d.ts +1 -0
  113. package/dist/utils/url/index.js +1 -0
  114. package/dist/utils/url/url.d.ts +46 -0
  115. package/dist/utils/url/url.js +28 -0
  116. package/dist/utils/uuidv4/index.d.ts +1 -0
  117. package/dist/utils/uuidv4/index.js +1 -0
  118. package/dist/utils/uuidv4/uuidv4.d.ts +12 -0
  119. package/dist/utils/uuidv4/uuidv4.js +11 -0
  120. 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,2 @@
1
+ export { UseDoubleClickReturn, useDoubleClick } from './use-double-click.js';
2
+ import 'react';
@@ -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,2 @@
1
+ export { useEventListener } from './use-event-listener.js';
2
+ import 'react';
@@ -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,2 @@
1
+ export { UseMultiSelectReturn, updateSelectedItems, useMultiSelect } from './use-multi-select.js';
2
+ import 'react';
@@ -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,2 @@
1
+ export { UsePopoverReturn, usePopover } from './use-popover.js';
2
+ import 'react';
@@ -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,2 @@
1
+ export { usePopoverHover } from './use-popover-hover.js';
2
+ import 'react';
@@ -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,2 @@
1
+ export { UseScrollOffsetTopReturn, useScrollOffsetTop } from './use-scroll-offset-top.js';
2
+ import 'react';
@@ -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 };