@studiocubics/hooks 0.0.1 → 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/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/useAnchorElement/useAnchorElement.d.ts +8 -0
- package/dist/useAnchorElement/useAnchorElement.js +2 -0
- package/dist/useAnchorElement/useAnchorElement.js.map +1 -0
- package/dist/useDelayedAction/useDelayedAction.d.ts +1 -0
- package/dist/useDelayedAction/useDelayedAction.js +2 -0
- package/dist/useDelayedAction/useDelayedAction.js.map +1 -0
- package/dist/useDisclosure/useDisclosure.d.ts +7 -0
- package/dist/useDisclosure/useDisclosure.js +2 -0
- package/dist/useDisclosure/useDisclosure.js.map +1 -0
- package/dist/useEventCallback/useEventCallback.d.ts +2 -0
- package/dist/useEventCallback/useEventCallback.js +2 -0
- package/dist/useEventCallback/useEventCallback.js.map +1 -0
- package/dist/useEventListener/useEventListener.d.ts +6 -0
- package/dist/useEventListener/useEventListener.js +2 -0
- package/dist/useEventListener/useEventListener.js.map +1 -0
- package/dist/useFormHelpers/useFormHelpers.d.ts +10 -0
- package/dist/useFormHelpers/useFormHelpers.js +2 -0
- package/dist/useFormHelpers/useFormHelpers.js.map +1 -0
- package/dist/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.d.ts +2 -0
- package/dist/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js +2 -0
- package/dist/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js.map +1 -0
- package/dist/useLocalStorage/useLocalStorage.d.ts +13 -0
- package/dist/useLocalStorage/useLocalStorage.js +2 -0
- package/dist/useLocalStorage/useLocalStorage.js.map +1 -0
- package/dist/useMounted/useMounted.d.ts +3 -0
- package/dist/useMounted/useMounted.js +2 -0
- package/dist/useMounted/useMounted.js.map +1 -0
- package/dist/useMousePosition/useMousePosition.d.ts +12 -0
- package/dist/useMousePosition/useMousePosition.js +2 -0
- package/dist/useMousePosition/useMousePosition.js.map +1 -0
- package/dist/useScreenSize/useScreenSize.d.ts +17 -0
- package/dist/useScreenSize/useScreenSize.js +2 -0
- package/dist/useScreenSize/useScreenSize.js.map +1 -0
- package/package.json +6 -6
- package/CHANGELOG.md +0 -9
- package/eslint.config.js +0 -21
- package/src/useAnchorElement/useAnchorElement.tsx +0 -15
- package/src/useDelayedAction/useDelayedAction.tsx +0 -12
- package/src/useDisclosure/useDisclosure.tsx +0 -36
- package/src/useEventCallback/useEventCallback.tsx +0 -26
- package/src/useEventListener/useEventListener.tsx +0 -92
- package/src/useFormHelpers/useFormHelpers.tsx +0 -29
- package/src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.tsx +0 -6
- package/src/useLocalStorage/useLocalStorage.tsx +0 -165
- package/src/useMounted/useMounted.tsx +0 -11
- package/src/useMousePosition/useMousePosition.tsx +0 -60
- package/src/useScreenSize/useScreenSize.tsx +0 -74
- package/tsconfig.json +0 -31
- /package/{src/index.ts → dist/index.d.ts} +0 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export{useAnchorElement}from"./useAnchorElement/useAnchorElement.js";export{useDelayedAction}from"./useDelayedAction/useDelayedAction.js";export{useDisclosure}from"./useDisclosure/useDisclosure.js";export{useEventCallback}from"./useEventCallback/useEventCallback.js";export{useEventListener}from"./useEventListener/useEventListener.js";export{useFormHelpers}from"./useFormHelpers/useFormHelpers.js";export{useIsomorphicLayoutEffect}from"./useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";export{useLocalStorage}from"./useLocalStorage/useLocalStorage.js";export{useMounted}from"./useMounted/useMounted.js";export{useMousePosition}from"./useMousePosition/useMousePosition.js";export{useScreenSize}from"./useScreenSize/useScreenSize.js";
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type MouseEvent } from "react";
|
|
2
|
+
export declare function useAnchorElement<T extends HTMLElement>(): {
|
|
3
|
+
open: boolean;
|
|
4
|
+
anchorEl: T | null;
|
|
5
|
+
handleClick: (event: MouseEvent<T>) => void;
|
|
6
|
+
handleClose: () => void;
|
|
7
|
+
setAnchorEl: import("react").Dispatch<import("react").SetStateAction<T | null>>;
|
|
8
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useState as n,useMemo as e}from"react";function l(){const[l,o]=n(null);return{open:e(()=>Boolean(l),[l]),anchorEl:l,handleClick:n=>{o(n.currentTarget)},handleClose:()=>{o(null)},setAnchorEl:o}}export{l as useAnchorElement};
|
|
2
|
+
//# sourceMappingURL=useAnchorElement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnchorElement.js","sources":["../../src/useAnchorElement/useAnchorElement.tsx"],"sourcesContent":["\"use client\";\n\nimport { type MouseEvent, useMemo, useState } from \"react\";\n\nexport function useAnchorElement<T extends HTMLElement>() {\n const [anchorEl, setAnchorEl] = useState<T | null>(null);\n const open = useMemo(() => Boolean(anchorEl), [anchorEl]);\n const handleClick = (event: MouseEvent<T>) => {\n setAnchorEl(event.currentTarget);\n };\n const handleClose = () => {\n setAnchorEl(null);\n };\n return { open, anchorEl, handleClick, handleClose, setAnchorEl };\n}\n"],"names":["useAnchorElement","anchorEl","setAnchorEl","useState","open","useMemo","Boolean","handleClick","event","currentTarget","handleClose"],"mappings":"oEAIgBA,IACd,MAAOC,EAAUC,GAAeC,EAAmB,MAQnD,MAAO,CAAEC,KAPIC,EAAQ,IAAMC,QAAQL,GAAW,CAACA,IAOhCA,WAAUM,YANJC,IACnBN,EAAYM,EAAMC,gBAKkBC,YAHlB,KAClBR,EAAY,OAEqCA,cACrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useDelayedAction(): (fn: Function, ms: number) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDelayedAction.js","sources":["../../src/useDelayedAction/useDelayedAction.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\n\nexport function useDelayedAction() {\n const delayedExecute = useCallback(async (fn: Function, ms: number) => {\n await new Promise((resolve) => setTimeout(resolve, ms));\n fn();\n }, []);\n\n return delayedExecute;\n}\n"],"names":["useDelayedAction","useCallback","async","fn","ms","Promise","resolve","setTimeout"],"mappings":"0DAIgBA,IAMd,OALuBC,EAAYC,MAAOC,EAAcC,WAChD,IAAIC,QAASC,GAAYC,WAAWD,EAASF,IACnDD,KACC,GAGL"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useState as n}from"react";function e(e=!1){const[o,t]=n(e);function c(){t(!1)}return{open:o,handleClose:c,handleStrictClose:function(n,e){"backdropClick"!==e&&"escapeKeyDown"!==e&&c()},handleOpen:function(){t(!0)},handleToggle:function(){t(n=>!n)}}}export{e as useDisclosure};
|
|
2
|
+
//# sourceMappingURL=useDisclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDisclosure.js","sources":["../../src/useDisclosure/useDisclosure.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\n\nexport function useDisclosure(initialState: boolean = false) {\n const [open, setOpen] = useState(initialState);\n\n function handleOpen() {\n setOpen(true);\n }\n function handleClose() {\n setOpen(false);\n }\n\n /**\n * Hijacking the handleClose function to prevent the dialog from closing when the user clicks outside the dialog or presses the escape key.\n * @param _ event not going to be used.\n * @param reason The reason the dialog was closed.\n */\n function handleStrictClose(_: {}, reason: \"backdropClick\" | \"escapeKeyDown\") {\n if (reason === \"backdropClick\" || reason === \"escapeKeyDown\") return;\n handleClose();\n }\n\n function handleToggle() {\n setOpen((prev) => !prev);\n }\n\n return {\n open,\n handleClose,\n handleStrictClose,\n handleOpen,\n handleToggle,\n };\n}\n"],"names":["useDisclosure","initialState","open","setOpen","useState","handleClose","handleStrictClose","_","reason","handleOpen","handleToggle","prev"],"mappings":"8CAIM,SAAUA,EAAcC,GAAwB,GACpD,MAAOC,EAAMC,GAAWC,EAASH,GAKjC,SAASI,IACPF,GAAQ,EACV,CAgBA,MAAO,CACLD,OACAG,cACAC,kBAZF,SAA2BC,EAAOC,GACjB,kBAAXA,GAAyC,kBAAXA,GAClCH,GACF,EAUEI,WAzBF,WACEN,GAAQ,EACV,EAwBEO,aATF,WACEP,EAASQ,IAAUA,EACrB,EASF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useRef as r,useCallback as e}from"react";import{useIsomorphicLayoutEffect as t}from"../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";function o(o){const n=r(()=>{throw new Error("Cannot call an event handler while rendering.")});return t(()=>{n.current=o},[o]),e((...r)=>n.current?.(...r),[n])}export{o as useEventCallback};
|
|
2
|
+
//# sourceMappingURL=useEventCallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEventCallback.js","sources":["../../src/useEventCallback/useEventCallback.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect\";\n\nexport function useEventCallback<Args extends unknown[], R>(\n fn: (...args: Args) => R\n): (...args: Args) => R;\nexport function useEventCallback<Args extends unknown[], R>(\n fn: ((...args: Args) => R) | undefined\n): ((...args: Args) => R) | undefined;\nexport function useEventCallback<Args extends unknown[], R>(\n fn: ((...args: Args) => R) | undefined\n): ((...args: Args) => R) | undefined {\n const ref = useRef<typeof fn>(() => {\n throw new Error(\"Cannot call an event handler while rendering.\");\n });\n\n useIsomorphicLayoutEffect(() => {\n ref.current = fn;\n }, [fn]);\n\n return useCallback((...args: Args) => ref.current?.(...args), [ref]) as (\n ...args: Args\n ) => R;\n}\n"],"names":["useEventCallback","fn","ref","useRef","Error","useIsomorphicLayoutEffect","current","useCallback","args"],"mappings":"mKAWM,SAAUA,EACdC,GAEA,MAAMC,EAAMC,EAAkB,KAC5B,MAAM,IAAIC,MAAM,mDAOlB,OAJAC,EAA0B,KACxBH,EAAII,QAAUL,GACb,CAACA,IAEGM,EAAY,IAAIC,IAAeN,EAAII,aAAaE,GAAO,CAACN,GAGjE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RefObject } from "react";
|
|
2
|
+
declare function useEventListener<K extends keyof MediaQueryListEventMap>(eventName: K, handler: (event: MediaQueryListEventMap[K]) => void, element: RefObject<MediaQueryList>, options?: boolean | AddEventListenerOptions): void;
|
|
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 & keyof SVGElementEventMap, T extends Element = K extends keyof HTMLElementEventMap ? HTMLDivElement : SVGElement>(eventName: K, handler: ((event: HTMLElementEventMap[K]) => void) | ((event: SVGElementEventMap[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
|
+
export { useEventListener };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useRef as e,useEffect as t}from"react";import{useIsomorphicLayoutEffect as r}from"../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";function n(n,o,c,s){const i=e(o);r(()=>{i.current=o},[o]),t(()=>{const e=c?.current??window;if(!e||!e.addEventListener)return;const t=e=>{i.current(e)};return e.addEventListener(n,t,s),()=>{e.removeEventListener(n,t,s)}},[n,c,s])}export{n as useEventListener};
|
|
2
|
+
//# sourceMappingURL=useEventListener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEventListener.js","sources":["../../src/useEventListener/useEventListener.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nimport type { RefObject } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect\";\n\n// MediaQueryList Event based useEventListener interface\nfunction useEventListener<K extends keyof MediaQueryListEventMap>(\n eventName: K,\n handler: (event: MediaQueryListEventMap[K]) => void,\n element: RefObject<MediaQueryList>,\n options?: boolean | AddEventListenerOptions,\n): void;\n\n// Window Event based useEventListener interface\nfunction useEventListener<K extends keyof WindowEventMap>(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n element?: undefined,\n options?: boolean | AddEventListenerOptions,\n): void;\n\n// Element Event based useEventListener interface\nfunction useEventListener<\n K extends keyof HTMLElementEventMap & keyof SVGElementEventMap,\n T extends Element = K extends keyof HTMLElementEventMap\n ? HTMLDivElement\n : SVGElement,\n>(\n eventName: K,\n handler:\n | ((event: HTMLElementEventMap[K]) => void)\n | ((event: SVGElementEventMap[K]) => void),\n element: RefObject<T>,\n options?: boolean | AddEventListenerOptions,\n): void;\n\n// Document Event based useEventListener interface\nfunction useEventListener<K extends keyof DocumentEventMap>(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n element: RefObject<Document>,\n options?: boolean | AddEventListenerOptions,\n): void;\n\nfunction useEventListener<\n KW extends keyof WindowEventMap,\n KH extends keyof HTMLElementEventMap & keyof SVGElementEventMap,\n KM extends keyof MediaQueryListEventMap,\n T extends HTMLElement | SVGAElement | MediaQueryList = HTMLElement,\n>(\n eventName: KW | KH | KM,\n handler: (\n event:\n | WindowEventMap[KW]\n | HTMLElementEventMap[KH]\n | SVGElementEventMap[KH]\n | MediaQueryListEventMap[KM]\n | Event,\n ) => void,\n element?: RefObject<T>,\n options?: boolean | AddEventListenerOptions,\n) {\n // Create a ref that stores handler\n const savedHandler = useRef(handler);\n\n useIsomorphicLayoutEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(() => {\n // Define the listening target\n const targetElement: T | Window = element?.current ?? window;\n\n if (!(targetElement && targetElement.addEventListener)) return;\n\n // Create event listener that calls handler function stored in ref\n const listener: typeof handler = (event) => {\n savedHandler.current(event);\n };\n\n targetElement.addEventListener(eventName, listener, options);\n\n // Remove event listener on cleanup\n return () => {\n targetElement.removeEventListener(eventName, listener, options);\n };\n }, [eventName, element, options]);\n}\n\nexport { useEventListener };\n"],"names":["useEventListener","eventName","handler","element","options","savedHandler","useRef","useIsomorphicLayoutEffect","current","useEffect","targetElement","window","addEventListener","listener","event","removeEventListener"],"mappings":"iKA8CA,SAASA,EAMPC,EACAC,EAQAC,EACAC,GAGA,MAAMC,EAAeC,EAAOJ,GAE5BK,EAA0B,KACxBF,EAAaG,QAAUN,GACtB,CAACA,IAEJO,EAAU,KAER,MAAMC,EAA4BP,GAASK,SAAWG,OAEtD,IAAMD,IAAiBA,EAAcE,iBAAmB,OAGxD,MAAMC,EAA4BC,IAChCT,EAAaG,QAAQM,IAMvB,OAHAJ,EAAcE,iBAAiBX,EAAWY,EAAUT,GAG7C,KACLM,EAAcK,oBAAoBd,EAAWY,EAAUT,KAExD,CAACH,EAAWE,EAASC,GAC1B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type FormHelpersProps = {
|
|
2
|
+
initialLoading?: boolean;
|
|
3
|
+
initialError?: string | unknown;
|
|
4
|
+
};
|
|
5
|
+
export declare function useFormHelpers(props: FormHelpersProps): {
|
|
6
|
+
loading: boolean;
|
|
7
|
+
error: {};
|
|
8
|
+
handleLoading: (l: boolean) => void;
|
|
9
|
+
handleError: (e: string | unknown) => void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useState as r}from"react";function n(n){const[o,i]=r(n?.initialLoading??!1),[e,t]=r(n?.initialError??"");return{loading:o,error:e,handleLoading:function(r){i(r)},handleError:function(r){"string"==typeof r&&t(r),r instanceof Error&&t(r.message),console.error(r)}}}export{n as useFormHelpers};
|
|
2
|
+
//# sourceMappingURL=useFormHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormHelpers.js","sources":["../../src/useFormHelpers/useFormHelpers.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\n\nexport type FormHelpersProps = {\n initialLoading?: boolean;\n initialError?: string | unknown;\n};\n\nexport function useFormHelpers(props: FormHelpersProps) {\n const [loading, setLoading] = useState(props?.initialLoading ?? false);\n const [error, setError] = useState(props?.initialError ?? \"\");\n\n function handleLoading(l: boolean) {\n setLoading(l);\n }\n function handleError(e: string | unknown) {\n if (typeof e === \"string\") setError(e);\n if (e instanceof Error) setError(e.message);\n console.error(e);\n }\n\n return {\n loading,\n error,\n handleLoading,\n handleError,\n };\n}\n"],"names":["useFormHelpers","props","loading","setLoading","useState","initialLoading","error","setError","initialError","handleLoading","l","handleError","e","Error","message","console"],"mappings":"8CASM,SAAUA,EAAeC,GAC7B,MAAOC,EAASC,GAAcC,EAASH,GAAOI,iBAAkB,IACzDC,EAAOC,GAAYH,EAASH,GAAOO,cAAgB,IAW1D,MAAO,CACLN,UACAI,QACAG,cAZF,SAAuBC,GACrBP,EAAWO,EACb,EAWEC,YAVF,SAAqBC,GACF,iBAANA,GAAgBL,EAASK,GAChCA,aAAaC,OAAON,EAASK,EAAEE,SACnCC,QAAQT,MAAMM,EAChB,EAQF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIsomorphicLayoutEffect.js","sources":["../../src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useLayoutEffect } from \"react\";\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n"],"names":["useIsomorphicLayoutEffect","window","useLayoutEffect","useEffect"],"mappings":"oEAIO,MAAMA,EACO,oBAAXC,OAAyBC,EAAkBC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Dispatch, SetStateAction } from "react";
|
|
2
|
+
declare global {
|
|
3
|
+
interface WindowEventMap {
|
|
4
|
+
"local-storage": CustomEvent;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
type UseLocalStorageOptions<T> = {
|
|
8
|
+
serializer?: (value: T) => string;
|
|
9
|
+
deserializer?: (value: string) => T;
|
|
10
|
+
initializeWithValue?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function useLocalStorage<T>(key: string, initialValue: T | (() => T), options?: UseLocalStorageOptions<T>): [T, Dispatch<SetStateAction<T>>, () => void];
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useCallback as e,useState as n,useEffect as t}from"react";import{useEventCallback as o}from"../useEventCallback/useEventCallback.js";import{useEventListener as r}from"../useEventListener/useEventListener.js";const i="undefined"==typeof window;function a(a,c,s={}){const{initializeWithValue:l=!0}=s,u=e(e=>s.serializer?s.serializer(e):JSON.stringify(e),[s]),g=e(e=>{if(s.deserializer)return s.deserializer(e);if("undefined"===e)return;const n=c instanceof Function?c():c;let t;try{t=JSON.parse(e)}catch(e){return console.error("Error parsing JSON:",e),n}return t},[s,c]),w=e(()=>{const e=c instanceof Function?c():c;if(i)return e;try{const n=window.localStorage.getItem(a);return n?g(n):e}catch(n){return console.warn(`Error reading localStorage key “${a}”:`,n),e}},[c,a,g]),[d,f]=n(()=>l?w():c instanceof Function?c():c),v=o(e=>{i&&console.warn(`Tried setting localStorage key “${a}” even though environment is not a client`);try{const n=e instanceof Function?e(w()):e;window.localStorage.setItem(a,u(n)),f(n),window.dispatchEvent(new StorageEvent("local-storage",{key:a}))}catch(e){console.warn(`Error setting localStorage key “${a}”:`,e)}}),m=o(()=>{i&&console.warn(`Tried removing localStorage key “${a}” even though environment is not a client`);const e=c instanceof Function?c():c;window.localStorage.removeItem(a),f(e),window.dispatchEvent(new StorageEvent("local-storage",{key:a}))});t(()=>{f(w())},[a]);const y=e(e=>{e.key&&e.key!==a||f(w())},[a,w]);return r("storage",y),r("local-storage",y),[d,v,m]}export{a as useLocalStorage};
|
|
2
|
+
//# sourceMappingURL=useLocalStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLocalStorage.js","sources":["../../src/useLocalStorage/useLocalStorage.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { Dispatch, SetStateAction } from \"react\";\nimport { useEventCallback } from \"../useEventCallback/useEventCallback\";\nimport { useEventListener } from \"../useEventListener/useEventListener\";\n\ndeclare global {\n interface WindowEventMap {\n \"local-storage\": CustomEvent;\n }\n}\n\ntype UseLocalStorageOptions<T> = {\n serializer?: (value: T) => string;\n deserializer?: (value: string) => T;\n initializeWithValue?: boolean;\n};\n\nconst IS_SERVER = typeof window === \"undefined\";\n\nexport function useLocalStorage<T>(\n key: string,\n initialValue: T | (() => T),\n options: UseLocalStorageOptions<T> = {},\n): [T, Dispatch<SetStateAction<T>>, () => void] {\n const { initializeWithValue = true } = options;\n\n const serializer = useCallback<(value: T) => string>(\n (value) => {\n if (options.serializer) {\n return options.serializer(value);\n }\n\n return JSON.stringify(value);\n },\n [options],\n );\n\n const deserializer = useCallback<(value: string) => T>(\n (value) => {\n if (options.deserializer) {\n return options.deserializer(value);\n }\n // Support 'undefined' as a value\n if (value === \"undefined\") {\n return undefined as unknown as T;\n }\n\n const defaultValue =\n initialValue instanceof Function ? initialValue() : initialValue;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return defaultValue; // Return initialValue if parsing fails\n }\n\n return parsed as T;\n },\n [options, initialValue],\n );\n\n // Get from local storage then\n // parse stored json or return initialValue\n const readValue = useCallback((): T => {\n const initialValueToUse =\n initialValue instanceof Function ? initialValue() : initialValue;\n\n // Prevent build error \"window is undefined\" but keep working\n if (IS_SERVER) {\n return initialValueToUse;\n }\n\n try {\n const raw = window.localStorage.getItem(key);\n return raw ? deserializer(raw) : initialValueToUse;\n } catch (error) {\n console.warn(`Error reading localStorage key “${key}”:`, error);\n return initialValueToUse;\n }\n }, [initialValue, key, deserializer]);\n\n const [storedValue, setStoredValue] = useState(() => {\n if (initializeWithValue) {\n return readValue();\n }\n\n return initialValue instanceof Function ? initialValue() : initialValue;\n });\n\n // Return a wrapped version of useState's setter function that ...\n // ... persists the new value to localStorage.\n const setValue: Dispatch<SetStateAction<T>> = useEventCallback((value) => {\n // Prevent build error \"window is undefined\" but keeps working\n if (IS_SERVER) {\n console.warn(\n `Tried setting localStorage key “${key}” even though environment is not a client`,\n );\n }\n\n try {\n // Allow value to be a function so we have the same API as useState\n const newValue = value instanceof Function ? value(readValue()) : value;\n\n // Save to local storage\n window.localStorage.setItem(key, serializer(newValue));\n\n // Save state\n setStoredValue(newValue);\n\n // We dispatch a custom event so every similar useLocalStorage hook is notified\n window.dispatchEvent(new StorageEvent(\"local-storage\", { key }));\n } catch (error) {\n console.warn(`Error setting localStorage key “${key}”:`, error);\n }\n });\n\n const removeValue = useEventCallback(() => {\n // Prevent build error \"window is undefined\" but keeps working\n if (IS_SERVER) {\n console.warn(\n `Tried removing localStorage key “${key}” even though environment is not a client`,\n );\n }\n\n const defaultValue =\n initialValue instanceof Function ? initialValue() : initialValue;\n\n // Remove the key from local storage\n window.localStorage.removeItem(key);\n\n // Save state with default value\n setStoredValue(defaultValue);\n\n // We dispatch a custom event so every similar useLocalStorage hook is notified\n window.dispatchEvent(new StorageEvent(\"local-storage\", { key }));\n });\n\n useEffect(() => {\n setStoredValue(readValue());\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key]);\n\n const handleStorageChange = useCallback(\n (event: StorageEvent | CustomEvent) => {\n if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {\n return;\n }\n setStoredValue(readValue());\n },\n [key, readValue],\n );\n\n // this only works for other documents, not the current one\n useEventListener(\"storage\", handleStorageChange);\n\n // this is a custom event, triggered in writeValueToLocalStorage\n // See: useLocalStorage()\n useEventListener(\"local-storage\", handleStorageChange);\n\n return [storedValue, setValue, removeValue];\n}\n"],"names":["IS_SERVER","window","useLocalStorage","key","initialValue","options","initializeWithValue","serializer","useCallback","value","JSON","stringify","deserializer","defaultValue","Function","parsed","parse","error","console","readValue","initialValueToUse","raw","localStorage","getItem","warn","storedValue","setStoredValue","useState","setValue","useEventCallback","newValue","setItem","dispatchEvent","StorageEvent","removeValue","removeItem","useEffect","handleStorageChange","event","useEventListener"],"mappings":"oOAmBA,MAAMA,EAA8B,oBAAXC,OAEnB,SAAUC,EACdC,EACAC,EACAC,EAAqC,CAAA,GAErC,MAAMC,oBAAEA,GAAsB,GAASD,EAEjCE,EAAaC,EAChBC,GACKJ,EAAQE,WACHF,EAAQE,WAAWE,GAGrBC,KAAKC,UAAUF,GAExB,CAACJ,IAGGO,EAAeJ,EAClBC,IACC,GAAIJ,EAAQO,aACV,OAAOP,EAAQO,aAAaH,GAG9B,GAAc,cAAVA,EACF,OAGF,MAAMI,EACJT,aAAwBU,SAAWV,IAAiBA,EAEtD,IAAIW,EACJ,IACEA,EAASL,KAAKM,MAAMP,EACtB,CAAE,MAAOQ,GAEP,OADAC,QAAQD,MAAM,sBAAuBA,GAC9BJ,CACT,CAEA,OAAOE,GAET,CAACV,EAASD,IAKNe,EAAYX,EAAY,KAC5B,MAAMY,EACJhB,aAAwBU,SAAWV,IAAiBA,EAGtD,GAAIJ,EACF,OAAOoB,EAGT,IACE,MAAMC,EAAMpB,OAAOqB,aAAaC,QAAQpB,GACxC,OAAOkB,EAAMT,EAAaS,GAAOD,CACnC,CAAE,MAAOH,GAEP,OADAC,QAAQM,KAAK,mCAAmCrB,MAASc,GAClDG,CACT,GACC,CAAChB,EAAcD,EAAKS,KAEhBa,EAAaC,GAAkBC,EAAS,IACzCrB,EACKa,IAGFf,aAAwBU,SAAWV,IAAiBA,GAKvDwB,EAAwCC,EAAkBpB,IAE1DT,GACFkB,QAAQM,KACN,mCAAmCrB,8CAIvC,IAEE,MAAM2B,EAAWrB,aAAiBK,SAAWL,EAAMU,KAAeV,EAGlER,OAAOqB,aAAaS,QAAQ5B,EAAKI,EAAWuB,IAG5CJ,EAAeI,GAGf7B,OAAO+B,cAAc,IAAIC,aAAa,gBAAiB,CAAE9B,QAC3D,CAAE,MAAOc,GACPC,QAAQM,KAAK,mCAAmCrB,MAASc,EAC3D,IAGIiB,EAAcL,EAAiB,KAE/B7B,GACFkB,QAAQM,KACN,oCAAoCrB,8CAIxC,MAAMU,EACJT,aAAwBU,SAAWV,IAAiBA,EAGtDH,OAAOqB,aAAaa,WAAWhC,GAG/BuB,EAAeb,GAGfZ,OAAO+B,cAAc,IAAIC,aAAa,gBAAiB,CAAE9B,WAG3DiC,EAAU,KACRV,EAAeP,MAEd,CAAChB,IAEJ,MAAMkC,EAAsB7B,EACzB8B,IACMA,EAAuBnC,KAAQmC,EAAuBnC,MAAQA,GAGnEuB,EAAeP,MAEjB,CAAChB,EAAKgB,IAUR,OANAoB,EAAiB,UAAWF,GAI5BE,EAAiB,gBAAiBF,GAE3B,CAACZ,EAAaG,EAAUM,EACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMounted.js","sources":["../../src/useMounted/useMounted.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nexport function useMounted() {\n const [mounted, setMounted] = useState(false);\n useEffect(() => {\n setMounted(true);\n }, []);\n return { mounted };\n}\n"],"names":["useMounted","mounted","setMounted","useState","useEffect"],"mappings":"sEAIgBA,IACd,MAAOC,EAASC,GAAcC,GAAS,GAIvC,OAHAC,EAAU,KACRF,GAAW,IACV,IACI,CAAED,UACX"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface PositionMatrix {
|
|
2
|
+
x: number | undefined;
|
|
3
|
+
y: number | undefined;
|
|
4
|
+
}
|
|
5
|
+
export declare function useMousePosition({ includeTouch }: {
|
|
6
|
+
includeTouch: Boolean;
|
|
7
|
+
}): {
|
|
8
|
+
mousePosition: PositionMatrix;
|
|
9
|
+
touchPosition: PositionMatrix;
|
|
10
|
+
mouseSpeed: number;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useState as e,useEffect as t}from"react";function o({includeTouch:o}){const[n,i]=e({x:void 0,y:void 0}),[c,s]=e({x:void 0,y:void 0}),[r,u]=e(0),[l,v]=e(void 0);return t(()=>{const e=e=>{let t,o;[t,o]=[e.clientX,e.clientY];var n=Math.abs(e.clientX-(l?.clientX?l?.clientX:0)),c=Math.abs(e.clientY-(l?.clientY?l?.clientY:0)),s=Math.sqrt(n*n+c*c),r=Math.round(10*s);u(r),i({x:t,y:o}),v(e)};return window.addEventListener("mousemove",e),()=>{window.removeEventListener("mousemove",e)}},[l]),t(()=>{const e=e=>{let t,o;if(e.touches){const n=e.touches[0];[t,o]=[n.clientX,n.clientY]}s({x:t,y:o})};return()=>{o&&window.removeEventListener("touchmove",e)}},[o]),{mousePosition:n,touchPosition:c,mouseSpeed:r}}export{o as useMousePosition};
|
|
2
|
+
//# sourceMappingURL=useMousePosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMousePosition.js","sources":["../../src/useMousePosition/useMousePosition.tsx"],"sourcesContent":["\"use client\";\nimport { useEffect, useState } from \"react\";\n\ninterface PositionMatrix {\n x: number | undefined;\n y: number | undefined;\n}\n\ntype Event = MouseEvent | undefined;\n\nexport function useMousePosition({ includeTouch }: { includeTouch: Boolean }) {\n const [mousePosition, setMousePosition] = useState<PositionMatrix>({\n x: undefined,\n y: undefined,\n });\n const [touchPosition, setTouchPosition] = useState<PositionMatrix>({\n x: undefined,\n y: undefined,\n });\n const [mouseSpeed, setMouseSpeed] = useState(0);\n const [prevEvent, setPrevEvent] = useState<Event>(undefined);\n useEffect(() => {\n const updateMousePosition = (currentEvent: MouseEvent) => {\n let x, y;\n [x, y] = [currentEvent.clientX, currentEvent.clientY];\n var movementX = Math.abs(\n currentEvent.clientX - (prevEvent?.clientX ? prevEvent?.clientX : 0)\n );\n var movementY = Math.abs(\n currentEvent.clientY - (prevEvent?.clientY ? prevEvent?.clientY : 0)\n );\n var movement = Math.sqrt(movementX * movementX + movementY * movementY);\n var speed = Math.round(10 * movement);\n setMouseSpeed(speed);\n setMousePosition({ x, y });\n setPrevEvent(currentEvent);\n // console.log(\"prevEvent\", prevEvent?.screenX);\n };\n window.addEventListener(\"mousemove\", updateMousePosition);\n return () => {\n window.removeEventListener(\"mousemove\", updateMousePosition);\n };\n }, [prevEvent]);\n useEffect(() => {\n const updateTouchPosition = (currentEvent: TouchEvent) => {\n let x, y;\n if (currentEvent.touches) {\n const touch = currentEvent.touches[0];\n [x, y] = [touch.clientX, touch.clientY];\n }\n setTouchPosition({ x, y });\n };\n return () => {\n if (includeTouch) {\n window.removeEventListener(\"touchmove\", updateTouchPosition);\n }\n };\n }, [includeTouch]);\n return { mousePosition, touchPosition, mouseSpeed };\n}\n"],"names":["useMousePosition","includeTouch","mousePosition","setMousePosition","useState","x","undefined","y","touchPosition","setTouchPosition","mouseSpeed","setMouseSpeed","prevEvent","setPrevEvent","useEffect","updateMousePosition","currentEvent","clientX","clientY","movementX","Math","abs","movementY","movement","sqrt","speed","round","window","addEventListener","removeEventListener","updateTouchPosition","touches","touch"],"mappings":"6DAUM,SAAUA,GAAiBC,aAAEA,IACjC,MAAOC,EAAeC,GAAoBC,EAAyB,CACjEC,OAAGC,EACHC,OAAGD,KAEEE,EAAeC,GAAoBL,EAAyB,CACjEC,OAAGC,EACHC,OAAGD,KAEEI,EAAYC,GAAiBP,EAAS,IACtCQ,EAAWC,GAAgBT,OAAgBE,GAsClD,OArCAQ,EAAU,KACR,MAAMC,EAAuBC,IAC3B,IAAIX,EAAGE,GACNF,EAAGE,GAAK,CAACS,EAAaC,QAASD,EAAaE,SAC7C,IAAIC,EAAYC,KAAKC,IACnBL,EAAaC,SAAWL,GAAWK,QAAUL,GAAWK,QAAU,IAEhEK,EAAYF,KAAKC,IACnBL,EAAaE,SAAWN,GAAWM,QAAUN,GAAWM,QAAU,IAEhEK,EAAWH,KAAKI,KAAKL,EAAYA,EAAYG,EAAYA,GACzDG,EAAQL,KAAKM,MAAM,GAAKH,GAC5BZ,EAAcc,GACdtB,EAAiB,CAAEE,IAAGE,MACtBM,EAAaG,IAIf,OADAW,OAAOC,iBAAiB,YAAab,GAC9B,KACLY,OAAOE,oBAAoB,YAAad,KAEzC,CAACH,IACJE,EAAU,KACR,MAAMgB,EAAuBd,IAC3B,IAAIX,EAAGE,EACP,GAAIS,EAAae,QAAS,CACxB,MAAMC,EAAQhB,EAAae,QAAQ,IAClC1B,EAAGE,GAAK,CAACyB,EAAMf,QAASe,EAAMd,QACjC,CACAT,EAAiB,CAAEJ,IAAGE,OAExB,MAAO,KACDN,GACF0B,OAAOE,oBAAoB,YAAaC,KAG3C,CAAC7B,IACG,CAAEC,gBAAeM,gBAAeE,aACzC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type ScreenSize = {
|
|
2
|
+
width: number;
|
|
3
|
+
height: number;
|
|
4
|
+
isSmall: boolean;
|
|
5
|
+
isMedium: boolean;
|
|
6
|
+
isLarge: boolean;
|
|
7
|
+
isXLarge: boolean;
|
|
8
|
+
ltSmall: boolean;
|
|
9
|
+
ltMedium: boolean;
|
|
10
|
+
ltLarge: boolean;
|
|
11
|
+
ltXLarge: boolean;
|
|
12
|
+
gtSmall: boolean;
|
|
13
|
+
gtMedium: boolean;
|
|
14
|
+
gtLarge: boolean;
|
|
15
|
+
} | null;
|
|
16
|
+
export declare function useScreenSize(): Partial<ScreenSize>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useState as e,useEffect as t}from"react";import{useLocalStorage as i}from"../useLocalStorage/useLocalStorage.js";const r=Object.freeze({sm:600,md:900,lg:1281,xl:1536});function n(){const[n,s]=i("screen",{width:0,height:0}),[d,o]=e({...n});return t(()=>{const e=n.width,t=n.height;o({width:e,height:t,isSmall:e<r.sm,isMedium:e>=r.sm&&e<r.md,isLarge:e>=r.md&&e<r.lg,isXLarge:e>=r.lg,ltSmall:e<r.sm,ltMedium:e<r.md,ltLarge:e<r.lg,ltXLarge:e<r.xl,gtSmall:e>=r.sm,gtMedium:e>=r.md,gtLarge:e>=r.lg})},[n]),t(()=>{if("undefined"==typeof window)return;const e=()=>{const e=window.innerWidth,t=window.innerHeight;s({width:e,height:t})};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[]),d}export{n as useScreenSize};
|
|
2
|
+
//# sourceMappingURL=useScreenSize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScreenSize.js","sources":["../../src/useScreenSize/useScreenSize.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useLocalStorage } from \"../useLocalStorage/useLocalStorage\";\n\ntype ScreenSize = {\n width: number;\n height: number;\n isSmall: boolean;\n isMedium: boolean;\n isLarge: boolean;\n isXLarge: boolean;\n ltSmall: boolean;\n ltMedium: boolean;\n ltLarge: boolean;\n ltXLarge: boolean;\n gtSmall: boolean;\n gtMedium: boolean;\n gtLarge: boolean;\n} | null;\n\n// Move breakpoints OUTSIDE. Prevents Rollup/minifiers from collapsing them.\nconst BREAKPOINTS = Object.freeze({\n sm: 600,\n md: 900,\n lg: 1281,\n xl: 1536,\n});\n\nexport function useScreenSize(): Partial<ScreenSize> {\n const [screenSize, setScreenSize] = useLocalStorage(\"screen\", {\n width: 0,\n height: 0,\n });\n const [size, setSize] = useState<Partial<ScreenSize>>({ ...screenSize });\n\n useEffect(() => {\n const width = screenSize.width;\n const height = screenSize.height;\n setSize({\n width,\n height,\n isSmall: width < BREAKPOINTS.sm,\n isMedium: width >= BREAKPOINTS.sm && width < BREAKPOINTS.md,\n isLarge: width >= BREAKPOINTS.md && width < BREAKPOINTS.lg,\n isXLarge: width >= BREAKPOINTS.lg,\n\n ltSmall: width < BREAKPOINTS.sm,\n ltMedium: width < BREAKPOINTS.md,\n ltLarge: width < BREAKPOINTS.lg,\n ltXLarge: width < BREAKPOINTS.xl,\n\n gtSmall: width >= BREAKPOINTS.sm,\n gtMedium: width >= BREAKPOINTS.md,\n gtLarge: width >= BREAKPOINTS.lg,\n });\n }, [screenSize]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const compute = () => {\n const width = window.innerWidth;\n const height = window.innerHeight;\n setScreenSize({ width, height });\n };\n\n compute();\n window.addEventListener(\"resize\", compute);\n return () => window.removeEventListener(\"resize\", compute);\n }, []);\n\n return size;\n}\n"],"names":["BREAKPOINTS","Object","freeze","sm","md","lg","xl","useScreenSize","screenSize","setScreenSize","useLocalStorage","width","height","size","setSize","useState","useEffect","isSmall","isMedium","isLarge","isXLarge","ltSmall","ltMedium","ltLarge","ltXLarge","gtSmall","gtMedium","gtLarge","window","compute","innerWidth","innerHeight","addEventListener","removeEventListener"],"mappings":"qIAsBA,MAAMA,EAAcC,OAAOC,OAAO,CAChCC,GAAI,IACJC,GAAI,IACJC,GAAI,KACJC,GAAI,gBAGUC,IACd,MAAOC,EAAYC,GAAiBC,EAAgB,SAAU,CAC5DC,MAAO,EACPC,OAAQ,KAEHC,EAAMC,GAAWC,EAA8B,IAAKP,IAsC3D,OApCAQ,EAAU,KACR,MAAML,EAAQH,EAAWG,MACnBC,EAASJ,EAAWI,OAC1BE,EAAQ,CACNH,QACAC,SACAK,QAASN,EAAQX,EAAYG,GAC7Be,SAAUP,GAASX,EAAYG,IAAMQ,EAAQX,EAAYI,GACzDe,QAASR,GAASX,EAAYI,IAAMO,EAAQX,EAAYK,GACxDe,SAAUT,GAASX,EAAYK,GAE/BgB,QAASV,EAAQX,EAAYG,GAC7BmB,SAAUX,EAAQX,EAAYI,GAC9BmB,QAASZ,EAAQX,EAAYK,GAC7BmB,SAAUb,EAAQX,EAAYM,GAE9BmB,QAASd,GAASX,EAAYG,GAC9BuB,SAAUf,GAASX,EAAYI,GAC/BuB,QAAShB,GAASX,EAAYK,MAE/B,CAACG,IAEJQ,EAAU,KACR,GAAsB,oBAAXY,OAAwB,OAEnC,MAAMC,EAAU,KACd,MAAMlB,EAAQiB,OAAOE,WACflB,EAASgB,OAAOG,YACtBtB,EAAc,CAAEE,QAAOC,YAKzB,OAFAiB,IACAD,OAAOI,iBAAiB,SAAUH,GAC3B,IAAMD,OAAOK,oBAAoB,SAAUJ,IACjD,IAEIhB,CACT"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"private": false,
|
|
8
|
-
"version": "0.0.
|
|
8
|
+
"version": "0.0.2",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"@studiocubics",
|
|
11
11
|
"cubics",
|
|
@@ -26,19 +26,19 @@
|
|
|
26
26
|
"./styles.css": "./dist/index.css"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"react": "^19.2.
|
|
30
|
-
"react-dom": "^19.2.
|
|
29
|
+
"react": "^19.2.4",
|
|
30
|
+
"react-dom": "^19.2.4"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@studiocubics/types": "^0.0.
|
|
33
|
+
"@studiocubics/types": "^0.0.2"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@eslint/js": "^9.39.1",
|
|
37
37
|
"@rollup/plugin-terser": "^0.4.4",
|
|
38
38
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
39
39
|
"@types/node": "^24.10.1",
|
|
40
|
-
"@types/react": "^19
|
|
41
|
-
"@types/react-dom": "^19
|
|
40
|
+
"@types/react": "^19",
|
|
41
|
+
"@types/react-dom": "^19",
|
|
42
42
|
"eslint": "^9.39.1",
|
|
43
43
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
44
44
|
"globals": "^16.5.0",
|
package/CHANGELOG.md
DELETED
package/eslint.config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import js from "@eslint/js";
|
|
2
|
-
import globals from "globals";
|
|
3
|
-
import reactHooks from "eslint-plugin-react-hooks";
|
|
4
|
-
import tseslint from "typescript-eslint";
|
|
5
|
-
import { defineConfig, globalIgnores } from "eslint/config";
|
|
6
|
-
|
|
7
|
-
export default defineConfig([
|
|
8
|
-
globalIgnores(["dist"]),
|
|
9
|
-
{
|
|
10
|
-
files: ["**/*.{ts,tsx}"],
|
|
11
|
-
extends: [
|
|
12
|
-
js.configs.recommended,
|
|
13
|
-
tseslint.configs.recommended,
|
|
14
|
-
reactHooks.configs.flat.recommended,
|
|
15
|
-
],
|
|
16
|
-
languageOptions: {
|
|
17
|
-
ecmaVersion: 2020,
|
|
18
|
-
globals: globals.browser,
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
]);
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { type MouseEvent, useMemo, useState } from "react";
|
|
4
|
-
|
|
5
|
-
export function useAnchorElement<T extends HTMLElement>() {
|
|
6
|
-
const [anchorEl, setAnchorEl] = useState<T | null>(null);
|
|
7
|
-
const open = useMemo(() => Boolean(anchorEl), [anchorEl]);
|
|
8
|
-
const handleClick = (event: MouseEvent<T>) => {
|
|
9
|
-
setAnchorEl(event.currentTarget);
|
|
10
|
-
};
|
|
11
|
-
const handleClose = () => {
|
|
12
|
-
setAnchorEl(null);
|
|
13
|
-
};
|
|
14
|
-
return { open, anchorEl, handleClick, handleClose, setAnchorEl };
|
|
15
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useCallback } from "react";
|
|
4
|
-
|
|
5
|
-
export function useDelayedAction() {
|
|
6
|
-
const delayedExecute = useCallback(async (fn: Function, ms: number) => {
|
|
7
|
-
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
|
-
fn();
|
|
9
|
-
}, []);
|
|
10
|
-
|
|
11
|
-
return delayedExecute;
|
|
12
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
|
|
5
|
-
export function useDisclosure(initialState: boolean = false) {
|
|
6
|
-
const [open, setOpen] = useState(initialState);
|
|
7
|
-
|
|
8
|
-
function handleOpen() {
|
|
9
|
-
setOpen(true);
|
|
10
|
-
}
|
|
11
|
-
function handleClose() {
|
|
12
|
-
setOpen(false);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Hijacking the handleClose function to prevent the dialog from closing when the user clicks outside the dialog or presses the escape key.
|
|
17
|
-
* @param _ event not going to be used.
|
|
18
|
-
* @param reason The reason the dialog was closed.
|
|
19
|
-
*/
|
|
20
|
-
function handleStrictClose(_: {}, reason: "backdropClick" | "escapeKeyDown") {
|
|
21
|
-
if (reason === "backdropClick" || reason === "escapeKeyDown") return;
|
|
22
|
-
handleClose();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function handleToggle() {
|
|
26
|
-
setOpen((prev) => !prev);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
open,
|
|
31
|
-
handleClose,
|
|
32
|
-
handleStrictClose,
|
|
33
|
-
handleOpen,
|
|
34
|
-
handleToggle,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useCallback, useRef } from "react";
|
|
4
|
-
import { useIsomorphicLayoutEffect } from "../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect";
|
|
5
|
-
|
|
6
|
-
export function useEventCallback<Args extends unknown[], R>(
|
|
7
|
-
fn: (...args: Args) => R
|
|
8
|
-
): (...args: Args) => R;
|
|
9
|
-
export function useEventCallback<Args extends unknown[], R>(
|
|
10
|
-
fn: ((...args: Args) => R) | undefined
|
|
11
|
-
): ((...args: Args) => R) | undefined;
|
|
12
|
-
export function useEventCallback<Args extends unknown[], R>(
|
|
13
|
-
fn: ((...args: Args) => R) | undefined
|
|
14
|
-
): ((...args: Args) => R) | undefined {
|
|
15
|
-
const ref = useRef<typeof fn>(() => {
|
|
16
|
-
throw new Error("Cannot call an event handler while rendering.");
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
useIsomorphicLayoutEffect(() => {
|
|
20
|
-
ref.current = fn;
|
|
21
|
-
}, [fn]);
|
|
22
|
-
|
|
23
|
-
return useCallback((...args: Args) => ref.current?.(...args), [ref]) as (
|
|
24
|
-
...args: Args
|
|
25
|
-
) => R;
|
|
26
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useEffect, useRef } from "react";
|
|
4
|
-
|
|
5
|
-
import type { RefObject } from "react";
|
|
6
|
-
import { useIsomorphicLayoutEffect } from "../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect";
|
|
7
|
-
|
|
8
|
-
// MediaQueryList Event based useEventListener interface
|
|
9
|
-
function useEventListener<K extends keyof MediaQueryListEventMap>(
|
|
10
|
-
eventName: K,
|
|
11
|
-
handler: (event: MediaQueryListEventMap[K]) => void,
|
|
12
|
-
element: RefObject<MediaQueryList>,
|
|
13
|
-
options?: boolean | AddEventListenerOptions,
|
|
14
|
-
): void;
|
|
15
|
-
|
|
16
|
-
// Window Event based useEventListener interface
|
|
17
|
-
function useEventListener<K extends keyof WindowEventMap>(
|
|
18
|
-
eventName: K,
|
|
19
|
-
handler: (event: WindowEventMap[K]) => void,
|
|
20
|
-
element?: undefined,
|
|
21
|
-
options?: boolean | AddEventListenerOptions,
|
|
22
|
-
): void;
|
|
23
|
-
|
|
24
|
-
// Element Event based useEventListener interface
|
|
25
|
-
function useEventListener<
|
|
26
|
-
K extends keyof HTMLElementEventMap & keyof SVGElementEventMap,
|
|
27
|
-
T extends Element = K extends keyof HTMLElementEventMap
|
|
28
|
-
? HTMLDivElement
|
|
29
|
-
: SVGElement,
|
|
30
|
-
>(
|
|
31
|
-
eventName: K,
|
|
32
|
-
handler:
|
|
33
|
-
| ((event: HTMLElementEventMap[K]) => void)
|
|
34
|
-
| ((event: SVGElementEventMap[K]) => void),
|
|
35
|
-
element: RefObject<T>,
|
|
36
|
-
options?: boolean | AddEventListenerOptions,
|
|
37
|
-
): void;
|
|
38
|
-
|
|
39
|
-
// Document Event based useEventListener interface
|
|
40
|
-
function useEventListener<K extends keyof DocumentEventMap>(
|
|
41
|
-
eventName: K,
|
|
42
|
-
handler: (event: DocumentEventMap[K]) => void,
|
|
43
|
-
element: RefObject<Document>,
|
|
44
|
-
options?: boolean | AddEventListenerOptions,
|
|
45
|
-
): void;
|
|
46
|
-
|
|
47
|
-
function useEventListener<
|
|
48
|
-
KW extends keyof WindowEventMap,
|
|
49
|
-
KH extends keyof HTMLElementEventMap & keyof SVGElementEventMap,
|
|
50
|
-
KM extends keyof MediaQueryListEventMap,
|
|
51
|
-
T extends HTMLElement | SVGAElement | MediaQueryList = HTMLElement,
|
|
52
|
-
>(
|
|
53
|
-
eventName: KW | KH | KM,
|
|
54
|
-
handler: (
|
|
55
|
-
event:
|
|
56
|
-
| WindowEventMap[KW]
|
|
57
|
-
| HTMLElementEventMap[KH]
|
|
58
|
-
| SVGElementEventMap[KH]
|
|
59
|
-
| MediaQueryListEventMap[KM]
|
|
60
|
-
| Event,
|
|
61
|
-
) => void,
|
|
62
|
-
element?: RefObject<T>,
|
|
63
|
-
options?: boolean | AddEventListenerOptions,
|
|
64
|
-
) {
|
|
65
|
-
// Create a ref that stores handler
|
|
66
|
-
const savedHandler = useRef(handler);
|
|
67
|
-
|
|
68
|
-
useIsomorphicLayoutEffect(() => {
|
|
69
|
-
savedHandler.current = handler;
|
|
70
|
-
}, [handler]);
|
|
71
|
-
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
// Define the listening target
|
|
74
|
-
const targetElement: T | Window = element?.current ?? window;
|
|
75
|
-
|
|
76
|
-
if (!(targetElement && targetElement.addEventListener)) return;
|
|
77
|
-
|
|
78
|
-
// Create event listener that calls handler function stored in ref
|
|
79
|
-
const listener: typeof handler = (event) => {
|
|
80
|
-
savedHandler.current(event);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
targetElement.addEventListener(eventName, listener, options);
|
|
84
|
-
|
|
85
|
-
// Remove event listener on cleanup
|
|
86
|
-
return () => {
|
|
87
|
-
targetElement.removeEventListener(eventName, listener, options);
|
|
88
|
-
};
|
|
89
|
-
}, [eventName, element, options]);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export { useEventListener };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
|
|
5
|
-
export type FormHelpersProps = {
|
|
6
|
-
initialLoading?: boolean;
|
|
7
|
-
initialError?: string | unknown;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export function useFormHelpers(props: FormHelpersProps) {
|
|
11
|
-
const [loading, setLoading] = useState(props?.initialLoading ?? false);
|
|
12
|
-
const [error, setError] = useState(props?.initialError ?? "");
|
|
13
|
-
|
|
14
|
-
function handleLoading(l: boolean) {
|
|
15
|
-
setLoading(l);
|
|
16
|
-
}
|
|
17
|
-
function handleError(e: string | unknown) {
|
|
18
|
-
if (typeof e === "string") setError(e);
|
|
19
|
-
if (e instanceof Error) setError(e.message);
|
|
20
|
-
console.error(e);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
loading,
|
|
25
|
-
error,
|
|
26
|
-
handleLoading,
|
|
27
|
-
handleError,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useCallback, useEffect, useState } from "react";
|
|
4
|
-
import type { Dispatch, SetStateAction } from "react";
|
|
5
|
-
import { useEventCallback } from "../useEventCallback/useEventCallback";
|
|
6
|
-
import { useEventListener } from "../useEventListener/useEventListener";
|
|
7
|
-
|
|
8
|
-
declare global {
|
|
9
|
-
interface WindowEventMap {
|
|
10
|
-
"local-storage": CustomEvent;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
type UseLocalStorageOptions<T> = {
|
|
15
|
-
serializer?: (value: T) => string;
|
|
16
|
-
deserializer?: (value: string) => T;
|
|
17
|
-
initializeWithValue?: boolean;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const IS_SERVER = typeof window === "undefined";
|
|
21
|
-
|
|
22
|
-
export function useLocalStorage<T>(
|
|
23
|
-
key: string,
|
|
24
|
-
initialValue: T | (() => T),
|
|
25
|
-
options: UseLocalStorageOptions<T> = {},
|
|
26
|
-
): [T, Dispatch<SetStateAction<T>>, () => void] {
|
|
27
|
-
const { initializeWithValue = true } = options;
|
|
28
|
-
|
|
29
|
-
const serializer = useCallback<(value: T) => string>(
|
|
30
|
-
(value) => {
|
|
31
|
-
if (options.serializer) {
|
|
32
|
-
return options.serializer(value);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return JSON.stringify(value);
|
|
36
|
-
},
|
|
37
|
-
[options],
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const deserializer = useCallback<(value: string) => T>(
|
|
41
|
-
(value) => {
|
|
42
|
-
if (options.deserializer) {
|
|
43
|
-
return options.deserializer(value);
|
|
44
|
-
}
|
|
45
|
-
// Support 'undefined' as a value
|
|
46
|
-
if (value === "undefined") {
|
|
47
|
-
return undefined as unknown as T;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const defaultValue =
|
|
51
|
-
initialValue instanceof Function ? initialValue() : initialValue;
|
|
52
|
-
|
|
53
|
-
let parsed: unknown;
|
|
54
|
-
try {
|
|
55
|
-
parsed = JSON.parse(value);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error("Error parsing JSON:", error);
|
|
58
|
-
return defaultValue; // Return initialValue if parsing fails
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return parsed as T;
|
|
62
|
-
},
|
|
63
|
-
[options, initialValue],
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
// Get from local storage then
|
|
67
|
-
// parse stored json or return initialValue
|
|
68
|
-
const readValue = useCallback((): T => {
|
|
69
|
-
const initialValueToUse =
|
|
70
|
-
initialValue instanceof Function ? initialValue() : initialValue;
|
|
71
|
-
|
|
72
|
-
// Prevent build error "window is undefined" but keep working
|
|
73
|
-
if (IS_SERVER) {
|
|
74
|
-
return initialValueToUse;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
const raw = window.localStorage.getItem(key);
|
|
79
|
-
return raw ? deserializer(raw) : initialValueToUse;
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.warn(`Error reading localStorage key “${key}”:`, error);
|
|
82
|
-
return initialValueToUse;
|
|
83
|
-
}
|
|
84
|
-
}, [initialValue, key, deserializer]);
|
|
85
|
-
|
|
86
|
-
const [storedValue, setStoredValue] = useState(() => {
|
|
87
|
-
if (initializeWithValue) {
|
|
88
|
-
return readValue();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return initialValue instanceof Function ? initialValue() : initialValue;
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Return a wrapped version of useState's setter function that ...
|
|
95
|
-
// ... persists the new value to localStorage.
|
|
96
|
-
const setValue: Dispatch<SetStateAction<T>> = useEventCallback((value) => {
|
|
97
|
-
// Prevent build error "window is undefined" but keeps working
|
|
98
|
-
if (IS_SERVER) {
|
|
99
|
-
console.warn(
|
|
100
|
-
`Tried setting localStorage key “${key}” even though environment is not a client`,
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
// Allow value to be a function so we have the same API as useState
|
|
106
|
-
const newValue = value instanceof Function ? value(readValue()) : value;
|
|
107
|
-
|
|
108
|
-
// Save to local storage
|
|
109
|
-
window.localStorage.setItem(key, serializer(newValue));
|
|
110
|
-
|
|
111
|
-
// Save state
|
|
112
|
-
setStoredValue(newValue);
|
|
113
|
-
|
|
114
|
-
// We dispatch a custom event so every similar useLocalStorage hook is notified
|
|
115
|
-
window.dispatchEvent(new StorageEvent("local-storage", { key }));
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.warn(`Error setting localStorage key “${key}”:`, error);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const removeValue = useEventCallback(() => {
|
|
122
|
-
// Prevent build error "window is undefined" but keeps working
|
|
123
|
-
if (IS_SERVER) {
|
|
124
|
-
console.warn(
|
|
125
|
-
`Tried removing localStorage key “${key}” even though environment is not a client`,
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const defaultValue =
|
|
130
|
-
initialValue instanceof Function ? initialValue() : initialValue;
|
|
131
|
-
|
|
132
|
-
// Remove the key from local storage
|
|
133
|
-
window.localStorage.removeItem(key);
|
|
134
|
-
|
|
135
|
-
// Save state with default value
|
|
136
|
-
setStoredValue(defaultValue);
|
|
137
|
-
|
|
138
|
-
// We dispatch a custom event so every similar useLocalStorage hook is notified
|
|
139
|
-
window.dispatchEvent(new StorageEvent("local-storage", { key }));
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
useEffect(() => {
|
|
143
|
-
setStoredValue(readValue());
|
|
144
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
145
|
-
}, [key]);
|
|
146
|
-
|
|
147
|
-
const handleStorageChange = useCallback(
|
|
148
|
-
(event: StorageEvent | CustomEvent) => {
|
|
149
|
-
if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
setStoredValue(readValue());
|
|
153
|
-
},
|
|
154
|
-
[key, readValue],
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
// this only works for other documents, not the current one
|
|
158
|
-
useEventListener("storage", handleStorageChange);
|
|
159
|
-
|
|
160
|
-
// this is a custom event, triggered in writeValueToLocalStorage
|
|
161
|
-
// See: useLocalStorage()
|
|
162
|
-
useEventListener("local-storage", handleStorageChange);
|
|
163
|
-
|
|
164
|
-
return [storedValue, setValue, removeValue];
|
|
165
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
|
|
4
|
-
interface PositionMatrix {
|
|
5
|
-
x: number | undefined;
|
|
6
|
-
y: number | undefined;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
type Event = MouseEvent | undefined;
|
|
10
|
-
|
|
11
|
-
export function useMousePosition({ includeTouch }: { includeTouch: Boolean }) {
|
|
12
|
-
const [mousePosition, setMousePosition] = useState<PositionMatrix>({
|
|
13
|
-
x: undefined,
|
|
14
|
-
y: undefined,
|
|
15
|
-
});
|
|
16
|
-
const [touchPosition, setTouchPosition] = useState<PositionMatrix>({
|
|
17
|
-
x: undefined,
|
|
18
|
-
y: undefined,
|
|
19
|
-
});
|
|
20
|
-
const [mouseSpeed, setMouseSpeed] = useState(0);
|
|
21
|
-
const [prevEvent, setPrevEvent] = useState<Event>(undefined);
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
const updateMousePosition = (currentEvent: MouseEvent) => {
|
|
24
|
-
let x, y;
|
|
25
|
-
[x, y] = [currentEvent.clientX, currentEvent.clientY];
|
|
26
|
-
var movementX = Math.abs(
|
|
27
|
-
currentEvent.clientX - (prevEvent?.clientX ? prevEvent?.clientX : 0)
|
|
28
|
-
);
|
|
29
|
-
var movementY = Math.abs(
|
|
30
|
-
currentEvent.clientY - (prevEvent?.clientY ? prevEvent?.clientY : 0)
|
|
31
|
-
);
|
|
32
|
-
var movement = Math.sqrt(movementX * movementX + movementY * movementY);
|
|
33
|
-
var speed = Math.round(10 * movement);
|
|
34
|
-
setMouseSpeed(speed);
|
|
35
|
-
setMousePosition({ x, y });
|
|
36
|
-
setPrevEvent(currentEvent);
|
|
37
|
-
// console.log("prevEvent", prevEvent?.screenX);
|
|
38
|
-
};
|
|
39
|
-
window.addEventListener("mousemove", updateMousePosition);
|
|
40
|
-
return () => {
|
|
41
|
-
window.removeEventListener("mousemove", updateMousePosition);
|
|
42
|
-
};
|
|
43
|
-
}, [prevEvent]);
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
const updateTouchPosition = (currentEvent: TouchEvent) => {
|
|
46
|
-
let x, y;
|
|
47
|
-
if (currentEvent.touches) {
|
|
48
|
-
const touch = currentEvent.touches[0];
|
|
49
|
-
[x, y] = [touch.clientX, touch.clientY];
|
|
50
|
-
}
|
|
51
|
-
setTouchPosition({ x, y });
|
|
52
|
-
};
|
|
53
|
-
return () => {
|
|
54
|
-
if (includeTouch) {
|
|
55
|
-
window.removeEventListener("touchmove", updateTouchPosition);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}, [includeTouch]);
|
|
59
|
-
return { mousePosition, touchPosition, mouseSpeed };
|
|
60
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState, useEffect } from "react";
|
|
4
|
-
import { useLocalStorage } from "../useLocalStorage/useLocalStorage";
|
|
5
|
-
|
|
6
|
-
type ScreenSize = {
|
|
7
|
-
width: number;
|
|
8
|
-
height: number;
|
|
9
|
-
isSmall: boolean;
|
|
10
|
-
isMedium: boolean;
|
|
11
|
-
isLarge: boolean;
|
|
12
|
-
isXLarge: boolean;
|
|
13
|
-
ltSmall: boolean;
|
|
14
|
-
ltMedium: boolean;
|
|
15
|
-
ltLarge: boolean;
|
|
16
|
-
ltXLarge: boolean;
|
|
17
|
-
gtSmall: boolean;
|
|
18
|
-
gtMedium: boolean;
|
|
19
|
-
gtLarge: boolean;
|
|
20
|
-
} | null;
|
|
21
|
-
|
|
22
|
-
// Move breakpoints OUTSIDE. Prevents Rollup/minifiers from collapsing them.
|
|
23
|
-
const BREAKPOINTS = Object.freeze({
|
|
24
|
-
sm: 600,
|
|
25
|
-
md: 900,
|
|
26
|
-
lg: 1281,
|
|
27
|
-
xl: 1536,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
export function useScreenSize(): Partial<ScreenSize> {
|
|
31
|
-
const [screenSize, setScreenSize] = useLocalStorage("screen", {
|
|
32
|
-
width: 0,
|
|
33
|
-
height: 0,
|
|
34
|
-
});
|
|
35
|
-
const [size, setSize] = useState<Partial<ScreenSize>>({ ...screenSize });
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
const width = screenSize.width;
|
|
39
|
-
const height = screenSize.height;
|
|
40
|
-
setSize({
|
|
41
|
-
width,
|
|
42
|
-
height,
|
|
43
|
-
isSmall: width < BREAKPOINTS.sm,
|
|
44
|
-
isMedium: width >= BREAKPOINTS.sm && width < BREAKPOINTS.md,
|
|
45
|
-
isLarge: width >= BREAKPOINTS.md && width < BREAKPOINTS.lg,
|
|
46
|
-
isXLarge: width >= BREAKPOINTS.lg,
|
|
47
|
-
|
|
48
|
-
ltSmall: width < BREAKPOINTS.sm,
|
|
49
|
-
ltMedium: width < BREAKPOINTS.md,
|
|
50
|
-
ltLarge: width < BREAKPOINTS.lg,
|
|
51
|
-
ltXLarge: width < BREAKPOINTS.xl,
|
|
52
|
-
|
|
53
|
-
gtSmall: width >= BREAKPOINTS.sm,
|
|
54
|
-
gtMedium: width >= BREAKPOINTS.md,
|
|
55
|
-
gtLarge: width >= BREAKPOINTS.lg,
|
|
56
|
-
});
|
|
57
|
-
}, [screenSize]);
|
|
58
|
-
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
if (typeof window === "undefined") return;
|
|
61
|
-
|
|
62
|
-
const compute = () => {
|
|
63
|
-
const width = window.innerWidth;
|
|
64
|
-
const height = window.innerHeight;
|
|
65
|
-
setScreenSize({ width, height });
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
compute();
|
|
69
|
-
window.addEventListener("resize", compute);
|
|
70
|
-
return () => window.removeEventListener("resize", compute);
|
|
71
|
-
}, []);
|
|
72
|
-
|
|
73
|
-
return size;
|
|
74
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
-
"target": "ES2022",
|
|
5
|
-
"useDefineForClassFields": true,
|
|
6
|
-
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"resolveJsonModule": true,
|
|
9
|
-
"allowJs": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
|
|
12
|
-
/* Bundler mode */
|
|
13
|
-
"moduleResolution": "bundler",
|
|
14
|
-
"verbatimModuleSyntax": true,
|
|
15
|
-
"moduleDetection": "force",
|
|
16
|
-
"noEmit": true,
|
|
17
|
-
"jsx": "react-jsx",
|
|
18
|
-
// Output
|
|
19
|
-
"declaration": true,
|
|
20
|
-
"outDir": "./dist",
|
|
21
|
-
|
|
22
|
-
/* Linting */
|
|
23
|
-
"strict": true,
|
|
24
|
-
"noUnusedLocals": true,
|
|
25
|
-
"noUnusedParameters": true,
|
|
26
|
-
"erasableSyntaxOnly": true,
|
|
27
|
-
"noFallthroughCasesInSwitch": true,
|
|
28
|
-
"noUncheckedSideEffectImports": true
|
|
29
|
-
},
|
|
30
|
-
"include": ["src"]
|
|
31
|
-
}
|
|
File without changes
|