minimal-shared 0.0.2 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/hooks/index.d.ts +2 -4
  4. package/dist/hooks/index.js +0 -2
  5. package/dist/hooks/use-back-to-top/use-back-to-top.js +1 -64
  6. package/dist/hooks/use-boolean/use-boolean.js +1 -24
  7. package/dist/hooks/use-client-rect/use-client-rect.js +1 -47
  8. package/dist/hooks/use-cookies/index.d.ts +1 -1
  9. package/dist/hooks/use-cookies/use-cookies.d.ts +11 -10
  10. package/dist/hooks/use-cookies/use-cookies.js +1 -110
  11. package/dist/hooks/use-copy-to-clipboard/use-copy-to-clipboard.js +1 -27
  12. package/dist/hooks/use-countdown-date/use-countdown-date.js +1 -41
  13. package/dist/hooks/use-countdown-seconds/use-countdown-seconds.js +1 -36
  14. package/dist/hooks/use-debounce/use-debounce.js +1 -17
  15. package/dist/hooks/use-double-click/use-double-click.js +1 -33
  16. package/dist/hooks/use-is-client/use-is-client.js +1 -12
  17. package/dist/hooks/use-local-storage/index.d.ts +1 -1
  18. package/dist/hooks/use-local-storage/use-local-storage.d.ts +11 -10
  19. package/dist/hooks/use-local-storage/use-local-storage.js +1 -113
  20. package/dist/hooks/use-multi-select/use-multi-select.js +1 -36
  21. package/dist/hooks/use-popover/use-popover.js +1 -21
  22. package/dist/hooks/use-popover-hover/use-popover-hover.js +1 -24
  23. package/dist/hooks/use-scroll-offset-top/use-scroll-offset-top.js +1 -29
  24. package/dist/hooks/use-set-state/use-set-state.d.ts +5 -5
  25. package/dist/hooks/use-set-state/use-set-state.js +1 -26
  26. package/dist/hooks/use-tabs/use-tabs.js +1 -16
  27. package/dist/index.d.ts +4 -6
  28. package/dist/utils/active-link/active-link.js +1 -43
  29. package/dist/utils/classes/classes.js +1 -14
  30. package/dist/utils/color/color.js +2 -40
  31. package/dist/utils/cookies/cookies.js +1 -46
  32. package/dist/utils/font/font.js +1 -20
  33. package/dist/utils/index.d.ts +2 -2
  34. package/dist/utils/local-storage/index.d.ts +1 -1
  35. package/dist/utils/local-storage/local-storage.d.ts +2 -14
  36. package/dist/utils/local-storage/local-storage.js +1 -51
  37. package/dist/utils/object/object.js +1 -10
  38. package/dist/utils/url/index.d.ts +1 -1
  39. package/dist/utils/url/url.d.ts +9 -1
  40. package/dist/utils/url/url.js +1 -28
  41. package/dist/utils/uuidv4/uuidv4.js +1 -11
  42. package/package.json +21 -17
  43. package/dist/hooks/use-event-listener/index.d.ts +0 -2
  44. package/dist/hooks/use-event-listener/index.js +0 -1
  45. package/dist/hooks/use-event-listener/use-event-listener.d.ts +0 -7
  46. package/dist/hooks/use-event-listener/use-event-listener.js +0 -23
  47. package/dist/hooks/use-text-input/index.d.ts +0 -2
  48. package/dist/hooks/use-text-input/index.js +0 -1
  49. package/dist/hooks/use-text-input/use-text-input.d.ts +0 -16
  50. package/dist/hooks/use-text-input/use-text-input.js +0 -16
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Minimal UI ([https://minimals.cc/](https://minimals.cc/))
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # @minimals shared
1
+ # minimal-shared
2
2
 
3
3
  Shared hooks and utils used by Mnimal UI and Zone UI.
@@ -1,19 +1,17 @@
1
1
  export { UseTabsReturn, useTabs } from './use-tabs/use-tabs.js';
2
2
  export { UseBooleanReturn, useBoolean } from './use-boolean/use-boolean.js';
3
3
  export { UsePopoverReturn, usePopover } from './use-popover/use-popover.js';
4
- export { UseCookiesReturn, useCookies } from './use-cookies/use-cookies.js';
4
+ export { UseCookiesOptions, UseCookiesReturn, useCookies } from './use-cookies/use-cookies.js';
5
5
  export { UseDebounceReturn, useDebounce } from './use-debounce/use-debounce.js';
6
6
  export { UseSetStateReturn, useSetState } from './use-set-state/use-set-state.js';
7
7
  export { UseIsClientReturn, useIsClient } from './use-is-client/use-is-client.js';
8
- export { UseTextInputReturn, useTextInput } from './use-text-input/use-text-input.js';
9
8
  export { UseBackToTopReturn, useBackToTop } from './use-back-to-top/use-back-to-top.js';
10
9
  export { UseClientRectReturn, useClientRect } from './use-client-rect/use-client-rect.js';
11
10
  export { UseMultiSelectReturn, updateSelectedItems, useMultiSelect } from './use-multi-select/use-multi-select.js';
12
11
  export { UseDoubleClickReturn, useDoubleClick } from './use-double-click/use-double-click.js';
13
- export { UseLocalStorageReturn, useLocalStorage } from './use-local-storage/use-local-storage.js';
12
+ export { UseLocalStorageOptions, UseLocalStorageReturn, useLocalStorage } from './use-local-storage/use-local-storage.js';
14
13
  export { usePopoverHover } from './use-popover-hover/use-popover-hover.js';
15
14
  export { UseCountdownDateReturn, useCountdownDate } from './use-countdown-date/use-countdown-date.js';
16
- export { useEventListener } from './use-event-listener/use-event-listener.js';
17
15
  export { UseScrollOffsetTopReturn, useScrollOffsetTop } from './use-scroll-offset-top/use-scroll-offset-top.js';
18
16
  export { UseCountdownSecondsReturn, useCountdownSeconds } from './use-countdown-seconds/use-countdown-seconds.js';
19
17
  export { CopiedValue, CopyFn, UseCopyToClipboardReturn, useCopyToClipboard } from './use-copy-to-clipboard/use-copy-to-clipboard.js';
@@ -5,7 +5,6 @@ export * from './use-cookies';
5
5
  export * from './use-debounce';
6
6
  export * from './use-set-state';
7
7
  export * from './use-is-client';
8
- export * from './use-text-input';
9
8
  export * from './use-back-to-top';
10
9
  export * from './use-client-rect';
11
10
  export * from './use-multi-select';
@@ -13,7 +12,6 @@ export * from './use-double-click';
13
12
  export * from './use-local-storage';
14
13
  export * from './use-popover-hover';
15
14
  export * from './use-countdown-date';
16
- export * from './use-event-listener';
17
15
  export * from './use-scroll-offset-top';
18
16
  export * from './use-countdown-seconds';
19
17
  export * from './use-copy-to-clipboard';
@@ -1,64 +1 @@
1
- // src/hooks/use-back-to-top/use-back-to-top.ts
2
- import { useMemo, useState, useEffect, useCallback } from "react";
3
- function useBackToTop(defaultValue, isDebounce) {
4
- const [isVisible, setIsVisible] = useState(false);
5
- const parseValue = parseValueInput(defaultValue);
6
- const handleScroll = useCallback(() => {
7
- const windowInnerHeight = window.innerHeight;
8
- const windowScrollY = Math.round(window.scrollY);
9
- const documentOffsetHeight = document.body.offsetHeight;
10
- const scrollProgress = Math.round(
11
- windowScrollY / (documentOffsetHeight - windowInnerHeight) * 100
12
- );
13
- if (parseValue.type === "percentage") {
14
- setIsVisible(scrollProgress >= parseValue.value);
15
- } else {
16
- const distanceValue = documentOffsetHeight - windowInnerHeight - windowScrollY;
17
- setIsVisible(parseValue.value >= distanceValue);
18
- }
19
- }, [parseValue.type, parseValue.value]);
20
- const debouncedHandleScroll = useMemo(() => {
21
- let timeoutId;
22
- return () => {
23
- clearTimeout(timeoutId);
24
- timeoutId = setTimeout(handleScroll, 100);
25
- };
26
- }, [handleScroll]);
27
- useEffect(() => {
28
- const scrollHandler = isDebounce ? debouncedHandleScroll : handleScroll;
29
- window.addEventListener("scroll", scrollHandler);
30
- return () => {
31
- window.removeEventListener("scroll", scrollHandler);
32
- };
33
- }, [debouncedHandleScroll, handleScroll, isDebounce]);
34
- const onBackToTop = () => {
35
- window.scrollTo({ top: 0, behavior: "smooth" });
36
- };
37
- return {
38
- isVisible,
39
- onBackToTop,
40
- setIsVisible
41
- };
42
- }
43
- function parseValueInput(inputValue) {
44
- let value;
45
- let type;
46
- if (typeof inputValue === "string") {
47
- if (inputValue.endsWith("%")) {
48
- value = Number(inputValue.slice(0, -1));
49
- if (isNaN(value)) {
50
- throw new Error("Invalid percentage value");
51
- }
52
- type = "percentage";
53
- } else {
54
- throw new Error("String input must end with %");
55
- }
56
- } else {
57
- value = inputValue;
58
- type = "number";
59
- }
60
- return { value, type };
61
- }
62
- export {
63
- useBackToTop
64
- };
1
+ import{useMemo as p,useState as m,useEffect as w,useCallback as b}from"react";function g(t,o){let[n,i]=m(!1),r=f(t),s=b(()=>{let e=window.innerHeight,c=Math.round(window.scrollY),a=document.body.offsetHeight,u=Math.round(c/(a-e)*100);if(r.type==="percentage")i(u>=r.value);else{let d=a-e-c;i(r.value>=d)}},[r.type,r.value]),l=p(()=>{let e;return()=>{clearTimeout(e),e=setTimeout(s,100)}},[s]);return w(()=>{let e=o?l:s;return window.addEventListener("scroll",e),()=>{window.removeEventListener("scroll",e)}},[l,s,o]),{isVisible:n,onBackToTop:()=>{window.scrollTo({top:0,behavior:"smooth"})},setIsVisible:i}}function f(t){let o,n;if(typeof t=="string")if(t.endsWith("%")){if(o=Number(t.slice(0,-1)),isNaN(o))throw new Error("Invalid percentage value");n="percentage"}else throw new Error("String input must end with %");else o=t,n="number";return{value:o,type:n}}export{g as useBackToTop};
@@ -1,24 +1 @@
1
- // src/hooks/use-boolean/use-boolean.ts
2
- import { useState, useCallback } from "react";
3
- function useBoolean(defaultValue = false) {
4
- const [value, setValue] = useState(defaultValue);
5
- const onTrue = useCallback(() => {
6
- setValue(true);
7
- }, []);
8
- const onFalse = useCallback(() => {
9
- setValue(false);
10
- }, []);
11
- const onToggle = useCallback(() => {
12
- setValue((prev) => !prev);
13
- }, []);
14
- return {
15
- value,
16
- onTrue,
17
- onFalse,
18
- onToggle,
19
- setValue
20
- };
21
- }
22
- export {
23
- useBoolean
24
- };
1
+ import{useState as u,useCallback as o}from"react";function i(t=!1){let[n,e]=u(t),a=o(()=>{e(!0)},[]),l=o(()=>{e(!1)},[]),s=o(()=>{e(r=>!r)},[]);return{value:n,onTrue:a,onFalse:l,onToggle:s,setValue:e}}export{i as useBoolean};
@@ -1,47 +1 @@
1
- // src/hooks/use-client-rect/use-client-rect.ts
2
- import { useRef, useMemo, useState, useEffect, useCallback, useLayoutEffect } from "react";
3
- function useClientRect(inputRef, eventType) {
4
- const initialRef = useRef(null);
5
- const elementRef = inputRef || initialRef;
6
- const [rect, setRect] = useState(void 0);
7
- const [scroll, setScroll] = useState(void 0);
8
- const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
9
- const handleBoundingClientRect = useCallback(() => {
10
- if (elementRef.current) {
11
- const clientRect = elementRef.current.getBoundingClientRect();
12
- setRect(clientRect);
13
- setScroll({
14
- scrollWidth: elementRef.current.scrollWidth,
15
- scrollHeight: elementRef.current.scrollHeight
16
- });
17
- }
18
- }, [elementRef]);
19
- useIsomorphicLayoutEffect(() => {
20
- handleBoundingClientRect();
21
- }, [handleBoundingClientRect]);
22
- useEffect(() => {
23
- const event = eventType || "resize";
24
- window.addEventListener(event, handleBoundingClientRect);
25
- return () => {
26
- window.removeEventListener(event, handleBoundingClientRect);
27
- };
28
- }, [eventType, handleBoundingClientRect]);
29
- const memoizedRectValue = useMemo(() => rect, [rect]);
30
- const memoizedScrollValue = useMemo(() => scroll, [scroll]);
31
- return {
32
- elementRef,
33
- top: memoizedRectValue?.top ?? 0,
34
- right: memoizedRectValue?.right ?? 0,
35
- bottom: memoizedRectValue?.bottom ?? 0,
36
- left: memoizedRectValue?.left ?? 0,
37
- x: memoizedRectValue?.x ?? 0,
38
- y: memoizedRectValue?.y ?? 0,
39
- width: memoizedRectValue?.width ?? 0,
40
- height: memoizedRectValue?.height ?? 0,
41
- scrollWidth: memoizedScrollValue?.scrollWidth ?? 0,
42
- scrollHeight: memoizedScrollValue?.scrollHeight ?? 0
43
- };
44
- }
45
- export {
46
- useClientRect
47
- };
1
+ import{useRef as a,useMemo as u,useState as s,useEffect as m,useCallback as g,useLayoutEffect as p}from"react";function w(d,r){let f=a(null),t=d||f,[o,h]=s(void 0),[c,R]=s(void 0),b=typeof window<"u"?p:m,n=g(()=>{if(t.current){let l=t.current.getBoundingClientRect();h(l),R({scrollWidth:t.current.scrollWidth,scrollHeight:t.current.scrollHeight})}},[t]);b(()=>{n()},[n]),m(()=>{let l=r||"resize";return window.addEventListener(l,n),()=>{window.removeEventListener(l,n)}},[r,n]);let e=u(()=>o,[o]),i=u(()=>c,[c]);return{elementRef:t,top:e?.top??0,right:e?.right??0,bottom:e?.bottom??0,left:e?.left??0,x:e?.x??0,y:e?.y??0,width:e?.width??0,height:e?.height??0,scrollWidth:i?.scrollWidth??0,scrollHeight:i?.scrollHeight??0}}export{w as useClientRect};
@@ -1 +1 @@
1
- export { UseCookiesReturn, useCookies } from './use-cookies.js';
1
+ export { UseCookiesOptions, UseCookiesReturn, useCookies } from './use-cookies.js';
@@ -3,18 +3,18 @@
3
3
  *
4
4
  * @param {string} key - The key for the cookie.
5
5
  * @param {T} initialState - The initial state value.
6
- * @param {T} defaultValues - The default values to reset to.
7
6
  * @param {Object} [options] - Optional settings.
7
+ * @param {boolean} [options.initializeWithValue=true] - Whether to initialize the cookie with the initial state value.
8
8
  * @param {number} [options.daysUntilExpiration] - Number of days until the cookie expires.
9
9
  *
10
10
  * @returns {UseCookiesReturn<T>} - An object containing:
11
11
  * - `state`: The current state.
12
- * - `resetState`: A function to reset the state to default values.
13
- * - `setState`: A function to update the state.
14
- * - `setField`: A function to update a specific field in the state.
12
+ * - `resetState`: A function to reset the state to the initial value and remove the cookie.
13
+ * - `setState`: A function to update the state and save it to the cookie.
14
+ * - `setField`: A function to update a specific field in the state and save it to the cookie.
15
15
  *
16
16
  * @example
17
- * const { state, setState, setField, resetState } = useCookies('user', { name: '', age: 0 }, { name: '', age: 0 });
17
+ * const { state, setState, setField, resetState } = useCookies('user', { name: '', age: 0 });
18
18
  *
19
19
  * return (
20
20
  * <div>
@@ -25,15 +25,16 @@
25
25
  * </div>
26
26
  * );
27
27
  */
28
+ type UseCookiesOptions = {
29
+ initializeWithValue?: boolean;
30
+ daysUntilExpiration?: number;
31
+ };
28
32
  type UseCookiesReturn<T> = {
29
33
  state: T;
30
34
  resetState: (defaultState?: T) => void;
31
35
  setState: (updateState: T | Partial<T>) => void;
32
36
  setField: (name: keyof T, updateValue: T[keyof T]) => void;
33
37
  };
34
- declare function useCookies<T>(key: string, initialState?: T, options?: {
35
- initOnLoad?: boolean;
36
- daysUntilExpiration?: number;
37
- }): UseCookiesReturn<T>;
38
+ declare function useCookies<T>(key: string, initialState?: T, options?: UseCookiesOptions): UseCookiesReturn<T>;
38
39
 
39
- export { type UseCookiesReturn, useCookies };
40
+ export { type UseCookiesOptions, type UseCookiesReturn, useCookies };
@@ -1,110 +1 @@
1
- // src/hooks/use-cookies/use-cookies.ts
2
- import { useMemo, useState, useEffect, useCallback } from "react";
3
-
4
- // src/utils/cookies/cookies.ts
5
- function getCookie(key) {
6
- try {
7
- const keyName = `${key}=`;
8
- const cDecoded = decodeURIComponent(document.cookie);
9
- const cArr = cDecoded.split("; ");
10
- for (const val of cArr) {
11
- if (val.startsWith(keyName)) {
12
- const cookieValue = val.substring(keyName.length);
13
- try {
14
- return JSON.parse(cookieValue);
15
- } catch {
16
- return cookieValue;
17
- }
18
- }
19
- }
20
- } catch {
21
- return null;
22
- }
23
- return null;
24
- }
25
- function setCookie(key, value, daysUntilExpiration = 0) {
26
- try {
27
- const serializedValue = encodeURIComponent(JSON.stringify(value));
28
- let cookieOptions = `${key}=${serializedValue}; path=/`;
29
- if (daysUntilExpiration > 0) {
30
- const expirationDate = new Date(Date.now() + daysUntilExpiration * 24 * 60 * 60 * 1e3);
31
- cookieOptions += `; expires=${expirationDate.toUTCString()}`;
32
- }
33
- document.cookie = cookieOptions;
34
- } catch (error) {
35
- console.error("Error while setting cookie:", error);
36
- }
37
- }
38
- function removeCookie(key) {
39
- try {
40
- document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
41
- } catch (error) {
42
- console.error("Error while removing cookie:", error);
43
- }
44
- }
45
-
46
- // src/hooks/use-cookies/use-cookies.ts
47
- function useCookies(key, initialState, options) {
48
- const isValuePresent = !!getCookie(key);
49
- const storedValue = getCookie(key) ?? initialState;
50
- const [state, set] = useState(storedValue);
51
- const { initOnLoad = true, daysUntilExpiration } = options ?? {};
52
- const hasMultipleValues = state && typeof state === "object";
53
- useEffect(() => {
54
- if (storedValue) {
55
- if (hasMultipleValues) {
56
- set((prevValue) => ({ ...prevValue, ...storedValue }));
57
- } else {
58
- set(storedValue);
59
- }
60
- if (!isValuePresent && initOnLoad) {
61
- setCookie(key, storedValue, daysUntilExpiration);
62
- }
63
- }
64
- }, []);
65
- const setState = useCallback(
66
- (updateState) => {
67
- if (hasMultipleValues) {
68
- set((prevValue) => {
69
- const updatedState = { ...prevValue, ...updateState };
70
- setCookie(key, updatedState, daysUntilExpiration);
71
- return updatedState;
72
- });
73
- } else {
74
- setCookie(key, updateState, daysUntilExpiration);
75
- set(updateState);
76
- }
77
- },
78
- [hasMultipleValues, key, daysUntilExpiration]
79
- );
80
- const setField = useCallback(
81
- (name, updateValue) => {
82
- if (hasMultipleValues) {
83
- setState({ [name]: updateValue });
84
- }
85
- },
86
- [hasMultipleValues, setState]
87
- );
88
- const resetState = useCallback(
89
- (defaultState) => {
90
- if (defaultState) {
91
- set(defaultState);
92
- }
93
- removeCookie(key);
94
- },
95
- [key]
96
- );
97
- const memoizedValue = useMemo(
98
- () => ({
99
- state,
100
- setState,
101
- setField,
102
- resetState
103
- }),
104
- [resetState, setField, setState, state]
105
- );
106
- return memoizedValue;
107
- }
108
- export {
109
- useCookies
110
- };
1
+ import{useMemo as h,useState as g,useEffect as x,useCallback as T}from"react";function k(o){try{let e=`${o}=`,n=decodeURIComponent(document.cookie).split("; ");for(let r of n)if(r.startsWith(e)){let s=r.substring(e.length);try{return JSON.parse(s)}catch{return s}}}catch{return null}return null}function l(o,e,i=0){try{let n=encodeURIComponent(JSON.stringify(e)),r=`${o}=${n}; path=/`;if(i>0){let s=new Date(Date.now()+i*24*60*60*1e3);r+=`; expires=${s.toUTCString()}`}document.cookie=r}catch(n){console.error("Error while setting cookie:",n)}}function C(o){try{document.cookie=`${o}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`}catch(e){console.error("Error while removing cookie:",e)}}function b(o,e,i){let{initializeWithValue:n=!0,daysUntilExpiration:r}=i??{},s=e&&typeof e=="object",[d,a]=g(e);x(()=>{let t=k(o);t?a(s?c=>({...c,...t}):t):e&&n&&l(o,e,r)},[]);let u=T(t=>{s?a(c=>{let m={...c,...t};return l(o,m,r),m}):(l(o,t,r),a(t))},[s,o,r]),p=T((t,c)=>{s&&u({[t]:c})},[s,u]),f=T(t=>{a(t??e),C(o)},[e,o]);return h(()=>({state:d,setState:u,setField:p,resetState:f}),[f,p,u,d])}export{b as useCookies};
@@ -1,27 +1 @@
1
- // src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.ts
2
- import { useState, useCallback } from "react";
3
- function useCopyToClipboard() {
4
- const [copiedText, setCopiedText] = useState(null);
5
- const copy = useCallback(
6
- async (text) => {
7
- if (!navigator?.clipboard) {
8
- console.warn("Clipboard not supported");
9
- return false;
10
- }
11
- try {
12
- await navigator.clipboard.writeText(text);
13
- setCopiedText(text);
14
- return true;
15
- } catch (error) {
16
- console.warn("Copy failed", error);
17
- setCopiedText(null);
18
- return false;
19
- }
20
- },
21
- [setCopiedText]
22
- );
23
- return { copy, copiedText };
24
- }
25
- export {
26
- useCopyToClipboard
27
- };
1
+ import{useState as p,useCallback as n}from"react";function l(){let[r,o]=p(null);return{copy:n(async e=>{if(!navigator?.clipboard)return console.warn("Clipboard not supported"),!1;try{return await navigator.clipboard.writeText(e),o(e),!0}catch(t){return console.warn("Copy failed",t),o(null),!1}},[o]),copiedText:r}}export{l as useCopyToClipboard};
@@ -1,41 +1 @@
1
- // src/hooks/use-countdown-date/use-countdown-date.ts
2
- import { useState, useEffect, useCallback } from "react";
3
- function useCountdownDate(targetDate, placeholder = "- -") {
4
- const [value, setValue] = useState({
5
- days: placeholder,
6
- hours: placeholder,
7
- minutes: placeholder,
8
- seconds: placeholder
9
- });
10
- const handleUpdate = useCallback(() => {
11
- const now = /* @__PURE__ */ new Date();
12
- const { days, hours, minutes, seconds } = calculateTimeDifference(targetDate, now);
13
- setValue({
14
- days: formatTime(days),
15
- hours: formatTime(hours),
16
- minutes: formatTime(minutes),
17
- seconds: formatTime(seconds)
18
- });
19
- }, [targetDate]);
20
- useEffect(() => {
21
- handleUpdate();
22
- const interval = setInterval(handleUpdate, 1e3);
23
- return () => clearInterval(interval);
24
- }, []);
25
- return value;
26
- }
27
- function formatTime(value) {
28
- return String(value).length === 1 ? `0${value}` : `${value}`;
29
- }
30
- function calculateTimeDifference(futureDate, currentDate) {
31
- const distance = futureDate.getTime() - currentDate.getTime();
32
- return {
33
- days: Math.floor(distance / (1e3 * 60 * 60 * 24)),
34
- hours: Math.floor(distance % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60)),
35
- minutes: Math.floor(distance % (1e3 * 60 * 60) / (1e3 * 60)),
36
- seconds: Math.floor(distance % (1e3 * 60) / 1e3)
37
- };
38
- }
39
- export {
40
- useCountdownDate
41
- };
1
+ import{useState as d,useEffect as f,useCallback as h}from"react";function y(t,n="- -"){let[e,u]=d({days:n,hours:n,minutes:n,seconds:n}),r=h(()=>{let o=new Date,{days:a,hours:i,minutes:c,seconds:m}=g(t,o);u({days:s(a),hours:s(i),minutes:s(c),seconds:s(m)})},[t]);return f(()=>{r();let o=setInterval(r,1e3);return()=>clearInterval(o)},[]),e}function s(t){return String(t).length===1?`0${t}`:`${t}`}function g(t,n){let e=t.getTime()-n.getTime();return{days:Math.floor(e/(1e3*60*60*24)),hours:Math.floor(e%(1e3*60*60*24)/(1e3*60*60)),minutes:Math.floor(e%(1e3*60*60)/(1e3*60)),seconds:Math.floor(e%(1e3*60)/1e3)}}export{y as useCountdownDate};
@@ -1,36 +1 @@
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
- };
1
+ import{useState as u,useEffect as S,useCallback as a}from"react";function f(t){let[e,n]=u(t),[o,s]=u(!1),i=a(()=>{s(!0)},[]),l=a(()=>{s(!1),n(t)},[t]);return S(()=>{let r=null;return o&&e>0?r=setInterval(()=>{n(c=>c-1)},1e3):e<=0&&s(!1),()=>{r&&clearInterval(r)}},[o,e]),{value:e,setValue:n,isCounting:o,start:i,reset:l}}export{f as useCountdownSeconds};
@@ -1,17 +1 @@
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
- };
1
+ import{useState as o,useEffect as s}from"react";function b(e,t=1e3){let[n,u]=o(e);return s(()=>{let r=setTimeout(()=>{u(e)},t);return()=>{clearTimeout(r)}},[e,t]),n}export{b as useDebounce};
@@ -1,33 +1 @@
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
- };
1
+ import{useRef as r,useCallback as i}from"react";function m({click:n,doubleClick:o,timeout:u=250}){let e=r(null),l=i(()=>{e.current&&(clearTimeout(e.current),e.current=null)},[]);return i(t=>{l(),n&&t.detail===1&&(e.current=setTimeout(()=>{n(t)},u)),t.detail%2===0&&o(t)},[n,o,u,l])}export{m as useDoubleClick};
@@ -1,12 +1 @@
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
- };
1
+ import{useState as n,useEffect as s}from"react";function i(){let[e,t]=n(!1);return s(()=>{t(!0)},[]),e}export{i as useIsClient};
@@ -1 +1 @@
1
- export { UseLocalStorageReturn, useLocalStorage } from './use-local-storage.js';
1
+ export { UseLocalStorageOptions, UseLocalStorageReturn, useLocalStorage } from './use-local-storage.js';
@@ -4,34 +4,35 @@
4
4
  * @param {string} key - The key for the local storage.
5
5
  * @param {T} initialState - The initial state value.
6
6
  * @param {Object} [options] - Optional settings.
7
- * @param {boolean} [options.initOnLoad=false] - Whether to initialize the local storage on load.
7
+ * @param {boolean} [options.initializeWithValue=true] - Whether to initialize the local storage with the initial state value.
8
8
  *
9
9
  * @returns {UseLocalStorageReturn<T>} - An object containing:
10
10
  * - `state`: The current state.
11
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.
12
+ * - `setState`: A function to update the state and save it to local storage.
13
+ * - `setField`: A function to update a specific field in the state and save it to local storage.
14
14
  *
15
15
  * @example
16
- * const { state, resetState, updateState, updateField } = useLocalStorage('settings', initialState);
16
+ * const { state, resetState, setState, setField } = useLocalStorage('settings', initialState);
17
17
  *
18
18
  * return (
19
19
  * <div>
20
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>
21
+ * <button onClick={() => setState({name: 'John', age: 20})}>Set State</button>
22
+ * <button onClick={() => setField('name', 'John')}>Set Name</button>
23
23
  * <button onClick={resetState}>Reset</button>
24
24
  * </div>
25
25
  * );
26
26
  */
27
+ type UseLocalStorageOptions = {
28
+ initializeWithValue?: boolean;
29
+ };
27
30
  type UseLocalStorageReturn<T> = {
28
31
  state: T;
29
32
  resetState: (defaultState?: T) => void;
30
33
  setState: (updateState: T | Partial<T>) => void;
31
34
  setField: (name: keyof T, updateValue: T[keyof T]) => void;
32
35
  };
33
- declare function useLocalStorage<T>(key: string, initialState?: T, options?: {
34
- initOnLoad?: boolean;
35
- }): UseLocalStorageReturn<T>;
36
+ declare function useLocalStorage<T>(key: string, initialState?: T, options?: UseLocalStorageOptions): UseLocalStorageReturn<T>;
36
37
 
37
- export { type UseLocalStorageReturn, useLocalStorage };
38
+ export { type UseLocalStorageOptions, type UseLocalStorageReturn, useLocalStorage };