@mantine/hooks 9.1.1 → 9.2.1
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/cjs/index.cjs +2 -0
- package/cjs/use-click-outside/use-click-outside.cjs.map +1 -1
- package/cjs/use-clipboard/use-clipboard.cjs.map +1 -1
- package/cjs/use-collapse/use-collapse.cjs.map +1 -1
- package/cjs/use-collapse/use-horizontal-collapse.cjs.map +1 -1
- package/cjs/use-color-scheme/use-color-scheme.cjs.map +1 -1
- package/cjs/use-counter/use-counter.cjs.map +1 -1
- package/cjs/use-debounced-callback/use-debounced-callback.cjs.map +1 -1
- package/cjs/use-debounced-state/use-debounced-state.cjs.map +1 -1
- package/cjs/use-debounced-value/use-debounced-value.cjs +3 -0
- package/cjs/use-debounced-value/use-debounced-value.cjs.map +1 -1
- package/cjs/use-did-update/use-did-update.cjs.map +1 -1
- package/cjs/use-disclosure/use-disclosure.cjs.map +1 -1
- package/cjs/use-document-title/use-document-title.cjs.map +1 -1
- package/cjs/use-document-visibility/use-document-visibility.cjs.map +1 -1
- package/cjs/use-drag/use-drag.cjs +266 -0
- package/cjs/use-drag/use-drag.cjs.map +1 -0
- package/cjs/use-event-listener/use-event-listener.cjs.map +1 -1
- package/cjs/use-eye-dropper/use-eye-dropper.cjs.map +1 -1
- package/cjs/use-favicon/use-favicon.cjs.map +1 -1
- package/cjs/use-fetch/use-fetch.cjs.map +1 -1
- package/cjs/use-file-dialog/use-file-dialog.cjs.map +1 -1
- package/cjs/use-floating-window/use-floating-window.cjs.map +1 -1
- package/cjs/use-focus-return/use-focus-return.cjs.map +1 -1
- package/cjs/use-focus-trap/scope-tab.cjs.map +1 -1
- package/cjs/use-focus-trap/tabbable.cjs.map +1 -1
- package/cjs/use-focus-trap/use-focus-trap.cjs.map +1 -1
- package/cjs/use-focus-within/use-focus-within.cjs.map +1 -1
- package/cjs/use-force-update/use-force-update.cjs.map +1 -1
- package/cjs/use-fullscreen/use-fullscreen.cjs.map +1 -1
- package/cjs/use-hash/use-hash.cjs.map +1 -1
- package/cjs/use-headroom/use-headroom.cjs.map +1 -1
- package/cjs/use-hotkeys/parse-hotkey.cjs.map +1 -1
- package/cjs/use-hotkeys/use-hotkeys.cjs.map +1 -1
- package/cjs/use-hover/use-hover.cjs.map +1 -1
- package/cjs/use-id/use-id.cjs.map +1 -1
- package/cjs/use-idle/use-idle.cjs.map +1 -1
- package/cjs/use-in-viewport/use-in-viewport.cjs.map +1 -1
- package/cjs/use-input-state/use-input-state.cjs.map +1 -1
- package/cjs/use-intersection/use-intersection.cjs.map +1 -1
- package/cjs/use-interval/use-interval.cjs.map +1 -1
- package/cjs/use-is-first-render/use-is-first-render.cjs.map +1 -1
- package/cjs/use-list-state/use-list-state.cjs.map +1 -1
- package/cjs/use-local-storage/create-storage.cjs.map +1 -1
- package/cjs/use-local-storage/use-local-storage.cjs.map +1 -1
- package/cjs/use-logger/use-logger.cjs.map +1 -1
- package/cjs/use-long-press/use-long-press.cjs.map +1 -1
- package/cjs/use-map/use-map.cjs.map +1 -1
- package/cjs/use-mask/use-mask.cjs.map +1 -1
- package/cjs/use-media-query/use-media-query.cjs.map +1 -1
- package/cjs/use-merged-ref/use-merged-ref.cjs.map +1 -1
- package/cjs/use-mounted/use-mounted.cjs.map +1 -1
- package/cjs/use-mouse/use-mouse.cjs.map +1 -1
- package/cjs/use-move/use-move.cjs.map +1 -1
- package/cjs/use-mutation-observer/use-mutation-observer.cjs.map +1 -1
- package/cjs/use-network/use-network.cjs.map +1 -1
- package/cjs/use-orientation/use-orientation.cjs.map +1 -1
- package/cjs/use-os/use-os.cjs.map +1 -1
- package/cjs/use-page-leave/use-page-leave.cjs.map +1 -1
- package/cjs/use-pagination/use-pagination.cjs.map +1 -1
- package/cjs/use-previous/use-previous.cjs.map +1 -1
- package/cjs/use-queue/use-queue.cjs.map +1 -1
- package/cjs/use-radial-move/use-radial-move.cjs +12 -4
- package/cjs/use-radial-move/use-radial-move.cjs.map +1 -1
- package/cjs/use-reduced-motion/use-reduced-motion.cjs.map +1 -1
- package/cjs/use-resize-observer/use-resize-observer.cjs.map +1 -1
- package/cjs/use-roving-index/use-roving-index.cjs.map +1 -1
- package/cjs/use-scroll-direction/use-scroll-direction.cjs.map +1 -1
- package/cjs/use-scroll-into-view/use-scroll-into-view.cjs.map +1 -1
- package/cjs/use-scroll-spy/use-scroll-spy.cjs.map +1 -1
- package/cjs/use-scroller/use-scroller.cjs.map +1 -1
- package/cjs/use-selection/use-selection.cjs.map +1 -1
- package/cjs/use-session-storage/use-session-storage.cjs.map +1 -1
- package/cjs/use-set/use-set.cjs.map +1 -1
- package/cjs/use-set-state/use-set-state.cjs.map +1 -1
- package/cjs/use-shallow-effect/use-shallow-effect.cjs.map +1 -1
- package/cjs/use-state-history/use-state-history.cjs.map +1 -1
- package/cjs/use-text-selection/use-text-selection.cjs.map +1 -1
- package/cjs/use-throttled-callback/use-throttled-callback.cjs.map +1 -1
- package/cjs/use-throttled-state/use-throttled-state.cjs.map +1 -1
- package/cjs/use-throttled-value/use-throttled-value.cjs.map +1 -1
- package/cjs/use-timeout/use-timeout.cjs.map +1 -1
- package/cjs/use-toggle/use-toggle.cjs.map +1 -1
- package/cjs/use-uncontrolled/use-uncontrolled.cjs.map +1 -1
- package/cjs/use-validated-state/use-validated-state.cjs.map +1 -1
- package/cjs/use-viewport-size/use-viewport-size.cjs.map +1 -1
- package/cjs/use-window-event/use-window-event.cjs.map +1 -1
- package/cjs/use-window-scroll/use-window-scroll.cjs.map +1 -1
- package/cjs/utils/clamp/clamp.cjs.map +1 -1
- package/cjs/utils/lower-first/lower-first.cjs.map +1 -1
- package/cjs/utils/random-id/random-id.cjs.map +1 -1
- package/cjs/utils/range/range.cjs.map +1 -1
- package/cjs/utils/shallow-equal/shallow-equal.cjs.map +1 -1
- package/cjs/utils/upper-first/upper-first.cjs.map +1 -1
- package/cjs/utils/use-callback-ref/use-callback-ref.cjs.map +1 -1
- package/esm/index.mjs +2 -1
- package/esm/use-click-outside/use-click-outside.mjs.map +1 -1
- package/esm/use-clipboard/use-clipboard.mjs.map +1 -1
- package/esm/use-collapse/use-collapse.mjs.map +1 -1
- package/esm/use-collapse/use-horizontal-collapse.mjs.map +1 -1
- package/esm/use-color-scheme/use-color-scheme.mjs.map +1 -1
- package/esm/use-counter/use-counter.mjs.map +1 -1
- package/esm/use-debounced-callback/use-debounced-callback.mjs.map +1 -1
- package/esm/use-debounced-state/use-debounced-state.mjs.map +1 -1
- package/esm/use-debounced-value/use-debounced-value.mjs +3 -0
- package/esm/use-debounced-value/use-debounced-value.mjs.map +1 -1
- package/esm/use-did-update/use-did-update.mjs.map +1 -1
- package/esm/use-disclosure/use-disclosure.mjs.map +1 -1
- package/esm/use-document-title/use-document-title.mjs.map +1 -1
- package/esm/use-document-visibility/use-document-visibility.mjs.map +1 -1
- package/esm/use-drag/use-drag.mjs +266 -0
- package/esm/use-drag/use-drag.mjs.map +1 -0
- package/esm/use-event-listener/use-event-listener.mjs.map +1 -1
- package/esm/use-eye-dropper/use-eye-dropper.mjs.map +1 -1
- package/esm/use-favicon/use-favicon.mjs.map +1 -1
- package/esm/use-fetch/use-fetch.mjs.map +1 -1
- package/esm/use-file-dialog/use-file-dialog.mjs.map +1 -1
- package/esm/use-floating-window/use-floating-window.mjs.map +1 -1
- package/esm/use-focus-return/use-focus-return.mjs.map +1 -1
- package/esm/use-focus-trap/scope-tab.mjs.map +1 -1
- package/esm/use-focus-trap/tabbable.mjs.map +1 -1
- package/esm/use-focus-trap/use-focus-trap.mjs.map +1 -1
- package/esm/use-focus-within/use-focus-within.mjs.map +1 -1
- package/esm/use-force-update/use-force-update.mjs.map +1 -1
- package/esm/use-fullscreen/use-fullscreen.mjs.map +1 -1
- package/esm/use-hash/use-hash.mjs.map +1 -1
- package/esm/use-headroom/use-headroom.mjs.map +1 -1
- package/esm/use-hotkeys/parse-hotkey.mjs.map +1 -1
- package/esm/use-hotkeys/use-hotkeys.mjs.map +1 -1
- package/esm/use-hover/use-hover.mjs.map +1 -1
- package/esm/use-id/use-id.mjs.map +1 -1
- package/esm/use-idle/use-idle.mjs.map +1 -1
- package/esm/use-in-viewport/use-in-viewport.mjs.map +1 -1
- package/esm/use-input-state/use-input-state.mjs.map +1 -1
- package/esm/use-intersection/use-intersection.mjs.map +1 -1
- package/esm/use-interval/use-interval.mjs.map +1 -1
- package/esm/use-is-first-render/use-is-first-render.mjs.map +1 -1
- package/esm/use-list-state/use-list-state.mjs.map +1 -1
- package/esm/use-local-storage/create-storage.mjs.map +1 -1
- package/esm/use-local-storage/use-local-storage.mjs.map +1 -1
- package/esm/use-logger/use-logger.mjs.map +1 -1
- package/esm/use-long-press/use-long-press.mjs.map +1 -1
- package/esm/use-map/use-map.mjs.map +1 -1
- package/esm/use-mask/use-mask.mjs.map +1 -1
- package/esm/use-media-query/use-media-query.mjs.map +1 -1
- package/esm/use-merged-ref/use-merged-ref.mjs.map +1 -1
- package/esm/use-mounted/use-mounted.mjs.map +1 -1
- package/esm/use-mouse/use-mouse.mjs.map +1 -1
- package/esm/use-move/use-move.mjs.map +1 -1
- package/esm/use-mutation-observer/use-mutation-observer.mjs.map +1 -1
- package/esm/use-network/use-network.mjs.map +1 -1
- package/esm/use-orientation/use-orientation.mjs.map +1 -1
- package/esm/use-os/use-os.mjs.map +1 -1
- package/esm/use-page-leave/use-page-leave.mjs.map +1 -1
- package/esm/use-pagination/use-pagination.mjs.map +1 -1
- package/esm/use-previous/use-previous.mjs.map +1 -1
- package/esm/use-queue/use-queue.mjs.map +1 -1
- package/esm/use-radial-move/use-radial-move.mjs +13 -5
- package/esm/use-radial-move/use-radial-move.mjs.map +1 -1
- package/esm/use-reduced-motion/use-reduced-motion.mjs.map +1 -1
- package/esm/use-resize-observer/use-resize-observer.mjs.map +1 -1
- package/esm/use-roving-index/use-roving-index.mjs.map +1 -1
- package/esm/use-scroll-direction/use-scroll-direction.mjs.map +1 -1
- package/esm/use-scroll-into-view/use-scroll-into-view.mjs.map +1 -1
- package/esm/use-scroll-spy/use-scroll-spy.mjs.map +1 -1
- package/esm/use-scroller/use-scroller.mjs.map +1 -1
- package/esm/use-selection/use-selection.mjs.map +1 -1
- package/esm/use-session-storage/use-session-storage.mjs.map +1 -1
- package/esm/use-set/use-set.mjs.map +1 -1
- package/esm/use-set-state/use-set-state.mjs.map +1 -1
- package/esm/use-shallow-effect/use-shallow-effect.mjs.map +1 -1
- package/esm/use-state-history/use-state-history.mjs.map +1 -1
- package/esm/use-text-selection/use-text-selection.mjs.map +1 -1
- package/esm/use-throttled-callback/use-throttled-callback.mjs.map +1 -1
- package/esm/use-throttled-state/use-throttled-state.mjs.map +1 -1
- package/esm/use-throttled-value/use-throttled-value.mjs.map +1 -1
- package/esm/use-timeout/use-timeout.mjs.map +1 -1
- package/esm/use-toggle/use-toggle.mjs.map +1 -1
- package/esm/use-uncontrolled/use-uncontrolled.mjs.map +1 -1
- package/esm/use-validated-state/use-validated-state.mjs.map +1 -1
- package/esm/use-viewport-size/use-viewport-size.mjs.map +1 -1
- package/esm/use-window-event/use-window-event.mjs.map +1 -1
- package/esm/use-window-scroll/use-window-scroll.mjs.map +1 -1
- package/esm/utils/clamp/clamp.mjs.map +1 -1
- package/esm/utils/lower-first/lower-first.mjs.map +1 -1
- package/esm/utils/random-id/random-id.mjs.map +1 -1
- package/esm/utils/range/range.mjs.map +1 -1
- package/esm/utils/shallow-equal/shallow-equal.mjs.map +1 -1
- package/esm/utils/upper-first/upper-first.mjs.map +1 -1
- package/esm/utils/use-callback-ref/use-callback-ref.mjs.map +1 -1
- package/lib/index.d.mts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/use-drag/use-drag.d.ts +60 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-eye-dropper.cjs","names":[],"sources":["../../src/use-eye-dropper/use-eye-dropper.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface EyeDropperOpenOptions {\n signal?: AbortSignal;\n}\n\nexport interface EyeDropperOpenReturnType {\n sRGBHex: string;\n}\n\nexport interface UseEyeDropperReturnValue {\n supported: boolean;\n open: (options?: EyeDropperOpenOptions) => Promise<EyeDropperOpenReturnType | undefined>;\n}\n\nexport function useEyeDropper(): UseEyeDropperReturnValue {\n const [supported, setSupported] = useState(false);\n\n useIsomorphicEffect(() => {\n setSupported(typeof window !== 'undefined' && !isOpera() && 'EyeDropper' in window);\n }, []);\n\n const open = useCallback(\n (options: EyeDropperOpenOptions = {}): Promise<EyeDropperOpenReturnType | undefined> => {\n if (supported) {\n const eyeDropper = new (window as any).EyeDropper();\n return eyeDropper.open(options);\n }\n\n return Promise.resolve(undefined);\n },\n [supported]\n );\n\n return { supported, open };\n}\n\nfunction isOpera() {\n return navigator.userAgent.includes('OPR');\n}\n"],"mappings":";;;;AAgBA,SAAgB,gBAA0C;CACxD,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,UAAyB,
|
|
1
|
+
{"version":3,"file":"use-eye-dropper.cjs","names":[],"sources":["../../src/use-eye-dropper/use-eye-dropper.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface EyeDropperOpenOptions {\n signal?: AbortSignal;\n}\n\nexport interface EyeDropperOpenReturnType {\n sRGBHex: string;\n}\n\nexport interface UseEyeDropperReturnValue {\n supported: boolean;\n open: (options?: EyeDropperOpenOptions) => Promise<EyeDropperOpenReturnType | undefined>;\n}\n\nexport function useEyeDropper(): UseEyeDropperReturnValue {\n const [supported, setSupported] = useState(false);\n\n useIsomorphicEffect(() => {\n setSupported(typeof window !== 'undefined' && !isOpera() && 'EyeDropper' in window);\n }, []);\n\n const open = useCallback(\n (options: EyeDropperOpenOptions = {}): Promise<EyeDropperOpenReturnType | undefined> => {\n if (supported) {\n const eyeDropper = new (window as any).EyeDropper();\n return eyeDropper.open(options);\n }\n\n return Promise.resolve(undefined);\n },\n [supported]\n );\n\n return { supported, open };\n}\n\nfunction isOpera() {\n return navigator.userAgent.includes('OPR');\n}\n"],"mappings":";;;;AAgBA,SAAgB,gBAA0C;CACxD,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,UAAyB,KAAK;CAEhD,8BAAA,0BAA0B;EACxB,aAAa,OAAO,WAAW,eAAe,CAAC,QAAQ,KAAK,gBAAgB,MAAM;CACpF,GAAG,CAAC,CAAC;CAcL,OAAO;EAAE;EAAW,OAAA,GAAA,MAAA,cAXjB,UAAiC,CAAC,MAAqD;GACtF,IAAI,WAEF,OAAO,IADiB,OAAe,WACvB,EAAE,KAAK,OAAO;GAGhC,OAAO,QAAQ,QAAQ,KAAA,CAAS;EAClC,GACA,CAAC,SAAS,CAGW;CAAE;AAC3B;AAEA,SAAS,UAAU;CACjB,OAAO,UAAU,UAAU,SAAS,KAAK;AAC3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-favicon.cjs","names":[],"sources":["../../src/use-favicon/use-favicon.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nconst MIME_TYPES: Record<string, string> = {\n ico: 'image/x-icon',\n png: 'image/png',\n svg: 'image/svg+xml',\n gif: 'image/gif',\n};\n\nexport function useFavicon(url: string) {\n const link = useRef<HTMLLinkElement>(null);\n\n useIsomorphicEffect(() => {\n if (!url) {\n return;\n }\n\n if (!link.current) {\n const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*=\"icon\"]');\n existingElements.forEach((element) => document.head.removeChild(element));\n\n const element = document.createElement('link');\n element.rel = 'shortcut icon';\n link.current = element;\n document.querySelector('head')!.appendChild(element);\n }\n\n const splittedUrl = url.split('.');\n const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();\n const mimeType = MIME_TYPES[extension];\n\n if (mimeType) {\n link.current.setAttribute('type', mimeType);\n } else {\n link.current.removeAttribute('type');\n }\n\n link.current.setAttribute('href', url);\n }, [url]);\n}\n"],"mappings":";;;;AAGA,MAAM,aAAqC;CACzC,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;
|
|
1
|
+
{"version":3,"file":"use-favicon.cjs","names":[],"sources":["../../src/use-favicon/use-favicon.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nconst MIME_TYPES: Record<string, string> = {\n ico: 'image/x-icon',\n png: 'image/png',\n svg: 'image/svg+xml',\n gif: 'image/gif',\n};\n\nexport function useFavicon(url: string) {\n const link = useRef<HTMLLinkElement>(null);\n\n useIsomorphicEffect(() => {\n if (!url) {\n return;\n }\n\n if (!link.current) {\n const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*=\"icon\"]');\n existingElements.forEach((element) => document.head.removeChild(element));\n\n const element = document.createElement('link');\n element.rel = 'shortcut icon';\n link.current = element;\n document.querySelector('head')!.appendChild(element);\n }\n\n const splittedUrl = url.split('.');\n const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();\n const mimeType = MIME_TYPES[extension];\n\n if (mimeType) {\n link.current.setAttribute('type', mimeType);\n } else {\n link.current.removeAttribute('type');\n }\n\n link.current.setAttribute('href', url);\n }, [url]);\n}\n"],"mappings":";;;;AAGA,MAAM,aAAqC;CACzC,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,WAAW,KAAa;CACtC,MAAM,QAAA,GAAA,MAAA,QAA+B,IAAI;CAEzC,8BAAA,0BAA0B;EACxB,IAAI,CAAC,KACH;EAGF,IAAI,CAAC,KAAK,SAAS;GAEjB,SADkC,iBAAkC,qBACrD,EAAE,SAAS,YAAY,SAAS,KAAK,YAAY,OAAO,CAAC;GAExE,MAAM,UAAU,SAAS,cAAc,MAAM;GAC7C,QAAQ,MAAM;GACd,KAAK,UAAU;GACf,SAAS,cAAc,MAAM,EAAG,YAAY,OAAO;EACrD;EAEA,MAAM,cAAc,IAAI,MAAM,GAAG;EAEjC,MAAM,WAAW,WADC,YAAY,YAAY,SAAS,GAAG,YAClB;EAEpC,IAAI,UACF,KAAK,QAAQ,aAAa,QAAQ,QAAQ;OAE1C,KAAK,QAAQ,gBAAgB,MAAM;EAGrC,KAAK,QAAQ,aAAa,QAAQ,GAAG;CACvC,GAAG,CAAC,GAAG,CAAC;AACV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-fetch.cjs","names":[],"sources":["../../src/use-fetch/use-fetch.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseFetchOptions extends RequestInit {\n autoInvoke?: boolean;\n}\n\nexport interface UseFetchReturnValue<T> {\n data: T | null;\n loading: boolean;\n error: Error | null;\n refetch: () => Promise<any>;\n abort: () => void;\n}\n\nexport function useFetch<T>(\n url: string,\n { autoInvoke = true, ...options }: UseFetchOptions = {}\n): UseFetchReturnValue<T> {\n const [data, setData] = useState<T | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const controller = useRef<AbortController | null>(null);\n\n const refetch = useCallback(() => {\n if (controller.current) {\n controller.current.abort();\n }\n\n controller.current = new AbortController();\n\n setLoading(true);\n\n return fetch(url, { ...options, signal: controller.current.signal })\n .then((res) => {\n if (!res.ok) {\n throw new Error(`Request failed with status ${res.status}`);\n }\n return res.json();\n })\n .then((res) => {\n setData(res);\n setLoading(false);\n return res as T;\n })\n .catch((err) => {\n setLoading(false);\n\n if (err.name !== 'AbortError') {\n setError(err);\n }\n\n return err;\n });\n }, [url, JSON.stringify(options)]);\n\n const abort = useCallback(() => {\n if (controller.current) {\n controller.current?.abort('');\n }\n }, []);\n\n useEffect(() => {\n if (autoInvoke) {\n refetch();\n }\n\n return () => {\n if (controller.current) {\n controller.current.abort('');\n }\n };\n }, [refetch, autoInvoke]);\n\n return { data, loading, error, refetch, abort };\n}\n\nexport namespace useFetch {\n export type Options = UseFetchOptions;\n export type ReturnValue<T> = UseFetchReturnValue<T>;\n}\n"],"mappings":";;;AAcA,SAAgB,SACd,KACA,EAAE,aAAa,MAAM,GAAG,YAA6B,
|
|
1
|
+
{"version":3,"file":"use-fetch.cjs","names":[],"sources":["../../src/use-fetch/use-fetch.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseFetchOptions extends RequestInit {\n autoInvoke?: boolean;\n}\n\nexport interface UseFetchReturnValue<T> {\n data: T | null;\n loading: boolean;\n error: Error | null;\n refetch: () => Promise<any>;\n abort: () => void;\n}\n\nexport function useFetch<T>(\n url: string,\n { autoInvoke = true, ...options }: UseFetchOptions = {}\n): UseFetchReturnValue<T> {\n const [data, setData] = useState<T | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const controller = useRef<AbortController | null>(null);\n\n const refetch = useCallback(() => {\n if (controller.current) {\n controller.current.abort();\n }\n\n controller.current = new AbortController();\n\n setLoading(true);\n\n return fetch(url, { ...options, signal: controller.current.signal })\n .then((res) => {\n if (!res.ok) {\n throw new Error(`Request failed with status ${res.status}`);\n }\n return res.json();\n })\n .then((res) => {\n setData(res);\n setLoading(false);\n return res as T;\n })\n .catch((err) => {\n setLoading(false);\n\n if (err.name !== 'AbortError') {\n setError(err);\n }\n\n return err;\n });\n }, [url, JSON.stringify(options)]);\n\n const abort = useCallback(() => {\n if (controller.current) {\n controller.current?.abort('');\n }\n }, []);\n\n useEffect(() => {\n if (autoInvoke) {\n refetch();\n }\n\n return () => {\n if (controller.current) {\n controller.current.abort('');\n }\n };\n }, [refetch, autoInvoke]);\n\n return { data, loading, error, refetch, abort };\n}\n\nexport namespace useFetch {\n export type Options = UseFetchOptions;\n export type ReturnValue<T> = UseFetchReturnValue<T>;\n}\n"],"mappings":";;;AAcA,SAAgB,SACd,KACA,EAAE,aAAa,MAAM,GAAG,YAA6B,CAAC,GAC9B;CACxB,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,UAA8B,IAAI;CAC/C,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,UAAuB,KAAK;CAC5C,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAmC,IAAI;CACrD,MAAM,cAAA,GAAA,MAAA,QAA4C,IAAI;CAEtD,MAAM,WAAA,GAAA,MAAA,mBAA4B;EAChC,IAAI,WAAW,SACb,WAAW,QAAQ,MAAM;EAG3B,WAAW,UAAU,IAAI,gBAAgB;EAEzC,WAAW,IAAI;EAEf,OAAO,MAAM,KAAK;GAAE,GAAG;GAAS,QAAQ,WAAW,QAAQ;EAAO,CAAC,EAChE,MAAM,QAAQ;GACb,IAAI,CAAC,IAAI,IACP,MAAM,IAAI,MAAM,8BAA8B,IAAI,QAAQ;GAE5D,OAAO,IAAI,KAAK;EAClB,CAAC,EACA,MAAM,QAAQ;GACb,QAAQ,GAAG;GACX,WAAW,KAAK;GAChB,OAAO;EACT,CAAC,EACA,OAAO,QAAQ;GACd,WAAW,KAAK;GAEhB,IAAI,IAAI,SAAS,cACf,SAAS,GAAG;GAGd,OAAO;EACT,CAAC;CACL,GAAG,CAAC,KAAK,KAAK,UAAU,OAAO,CAAC,CAAC;CAEjC,MAAM,SAAA,GAAA,MAAA,mBAA0B;EAC9B,IAAI,WAAW,SACb,WAAW,SAAS,MAAM,EAAE;CAEhC,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,iBAAgB;EACd,IAAI,YACF,QAAQ;EAGV,aAAa;GACX,IAAI,WAAW,SACb,WAAW,QAAQ,MAAM,EAAE;EAE/B;CACF,GAAG,CAAC,SAAS,UAAU,CAAC;CAExB,OAAO;EAAE;EAAM;EAAS;EAAO;EAAS;CAAM;AAChD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-file-dialog.cjs","names":[],"sources":["../../src/use-file-dialog/use-file-dialog.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface UseFileDialogOptions {\n /** Determines whether multiple files are allowed, `true` by default */\n multiple?: boolean;\n\n /** `accept` attribute of the file input, '*' by default */\n accept?: string;\n\n /** `capture` attribute of the file input */\n capture?: string;\n\n /** Determines whether the user can pick a directory instead of file, `false` by default */\n directory?: boolean;\n\n /** Determines whether the file input state should be reset when the file dialog is opened, `false` by default */\n resetOnOpen?: boolean;\n\n /** Initial selected files */\n initialFiles?: FileList | File[];\n\n /** Called when files are selected */\n onChange?: (files: FileList | null) => void;\n\n /** Called when file dialog is canceled */\n onCancel?: () => void;\n}\n\nconst defaultOptions: UseFileDialogOptions = {\n multiple: true,\n accept: '*',\n};\n\nfunction getInitialFilesList(files: UseFileDialogOptions['initialFiles']): FileList | null {\n if (!files) {\n return null;\n }\n\n if (files instanceof FileList) {\n return files;\n }\n\n const result = new DataTransfer();\n for (const file of files) {\n result.items.add(file);\n }\n\n return result.files;\n}\n\nfunction createInput(options: UseFileDialogOptions) {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const input = document.createElement('input');\n input.type = 'file';\n\n if (options.accept) {\n input.accept = options.accept;\n }\n\n if (options.multiple) {\n input.multiple = options.multiple;\n }\n\n if (options.capture) {\n input.capture = options.capture;\n }\n\n if (options.directory) {\n input.webkitdirectory = options.directory;\n }\n\n input.style.display = 'none';\n return input;\n}\n\nexport interface UseFileDialogReturnValue {\n files: FileList | null;\n open: () => void;\n reset: () => void;\n}\n\nexport function useFileDialog(input: UseFileDialogOptions = {}): UseFileDialogReturnValue {\n const options: UseFileDialogOptions = { ...defaultOptions, ...input };\n const [files, setFiles] = useState<FileList | null>(getInitialFilesList(options.initialFiles));\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const handleChange = useCallback(\n (event: Event) => {\n const target = event.target as HTMLInputElement;\n if (target?.files) {\n setFiles(target.files);\n options.onChange?.(target.files);\n }\n },\n [options.onChange]\n );\n\n const createAndSetupInput = useCallback(() => {\n inputRef.current?.remove();\n inputRef.current = createInput(options);\n\n if (inputRef.current) {\n inputRef.current.addEventListener('change', handleChange, { once: true });\n if (options.onCancel) {\n inputRef.current.addEventListener('cancel', options.onCancel, { once: true });\n }\n document.body.appendChild(inputRef.current);\n }\n }, [options, handleChange]);\n\n useIsomorphicEffect(() => {\n createAndSetupInput();\n return () => inputRef.current?.remove();\n }, []);\n\n const reset = useCallback(() => {\n setFiles(null);\n options.onChange?.(null);\n }, [options.onChange]);\n\n const open = useCallback(() => {\n if (options.resetOnOpen) {\n reset();\n }\n\n createAndSetupInput();\n inputRef.current?.click();\n }, [options.resetOnOpen, reset, createAndSetupInput]);\n\n return { files, open, reset };\n}\n\nexport namespace useFileDialog {\n export type Options = UseFileDialogOptions;\n export type ReturnValue = UseFileDialogReturnValue;\n}\n"],"mappings":";;;;AA6BA,MAAM,iBAAuC;CAC3C,UAAU;CACV,QAAQ;
|
|
1
|
+
{"version":3,"file":"use-file-dialog.cjs","names":[],"sources":["../../src/use-file-dialog/use-file-dialog.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface UseFileDialogOptions {\n /** Determines whether multiple files are allowed, `true` by default */\n multiple?: boolean;\n\n /** `accept` attribute of the file input, '*' by default */\n accept?: string;\n\n /** `capture` attribute of the file input */\n capture?: string;\n\n /** Determines whether the user can pick a directory instead of file, `false` by default */\n directory?: boolean;\n\n /** Determines whether the file input state should be reset when the file dialog is opened, `false` by default */\n resetOnOpen?: boolean;\n\n /** Initial selected files */\n initialFiles?: FileList | File[];\n\n /** Called when files are selected */\n onChange?: (files: FileList | null) => void;\n\n /** Called when file dialog is canceled */\n onCancel?: () => void;\n}\n\nconst defaultOptions: UseFileDialogOptions = {\n multiple: true,\n accept: '*',\n};\n\nfunction getInitialFilesList(files: UseFileDialogOptions['initialFiles']): FileList | null {\n if (!files) {\n return null;\n }\n\n if (files instanceof FileList) {\n return files;\n }\n\n const result = new DataTransfer();\n for (const file of files) {\n result.items.add(file);\n }\n\n return result.files;\n}\n\nfunction createInput(options: UseFileDialogOptions) {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const input = document.createElement('input');\n input.type = 'file';\n\n if (options.accept) {\n input.accept = options.accept;\n }\n\n if (options.multiple) {\n input.multiple = options.multiple;\n }\n\n if (options.capture) {\n input.capture = options.capture;\n }\n\n if (options.directory) {\n input.webkitdirectory = options.directory;\n }\n\n input.style.display = 'none';\n return input;\n}\n\nexport interface UseFileDialogReturnValue {\n files: FileList | null;\n open: () => void;\n reset: () => void;\n}\n\nexport function useFileDialog(input: UseFileDialogOptions = {}): UseFileDialogReturnValue {\n const options: UseFileDialogOptions = { ...defaultOptions, ...input };\n const [files, setFiles] = useState<FileList | null>(getInitialFilesList(options.initialFiles));\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const handleChange = useCallback(\n (event: Event) => {\n const target = event.target as HTMLInputElement;\n if (target?.files) {\n setFiles(target.files);\n options.onChange?.(target.files);\n }\n },\n [options.onChange]\n );\n\n const createAndSetupInput = useCallback(() => {\n inputRef.current?.remove();\n inputRef.current = createInput(options);\n\n if (inputRef.current) {\n inputRef.current.addEventListener('change', handleChange, { once: true });\n if (options.onCancel) {\n inputRef.current.addEventListener('cancel', options.onCancel, { once: true });\n }\n document.body.appendChild(inputRef.current);\n }\n }, [options, handleChange]);\n\n useIsomorphicEffect(() => {\n createAndSetupInput();\n return () => inputRef.current?.remove();\n }, []);\n\n const reset = useCallback(() => {\n setFiles(null);\n options.onChange?.(null);\n }, [options.onChange]);\n\n const open = useCallback(() => {\n if (options.resetOnOpen) {\n reset();\n }\n\n createAndSetupInput();\n inputRef.current?.click();\n }, [options.resetOnOpen, reset, createAndSetupInput]);\n\n return { files, open, reset };\n}\n\nexport namespace useFileDialog {\n export type Options = UseFileDialogOptions;\n export type ReturnValue = UseFileDialogReturnValue;\n}\n"],"mappings":";;;;AA6BA,MAAM,iBAAuC;CAC3C,UAAU;CACV,QAAQ;AACV;AAEA,SAAS,oBAAoB,OAA8D;CACzF,IAAI,CAAC,OACH,OAAO;CAGT,IAAI,iBAAiB,UACnB,OAAO;CAGT,MAAM,SAAS,IAAI,aAAa;CAChC,KAAK,MAAM,QAAQ,OACjB,OAAO,MAAM,IAAI,IAAI;CAGvB,OAAO,OAAO;AAChB;AAEA,SAAS,YAAY,SAA+B;CAClD,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,MAAM,QAAQ,SAAS,cAAc,OAAO;CAC5C,MAAM,OAAO;CAEb,IAAI,QAAQ,QACV,MAAM,SAAS,QAAQ;CAGzB,IAAI,QAAQ,UACV,MAAM,WAAW,QAAQ;CAG3B,IAAI,QAAQ,SACV,MAAM,UAAU,QAAQ;CAG1B,IAAI,QAAQ,WACV,MAAM,kBAAkB,QAAQ;CAGlC,MAAM,MAAM,UAAU;CACtB,OAAO;AACT;AAQA,SAAgB,cAAc,QAA8B,CAAC,GAA6B;CACxF,MAAM,UAAgC;EAAE,GAAG;EAAgB,GAAG;CAAM;CACpE,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAsC,oBAAoB,QAAQ,YAAY,CAAC;CAC7F,MAAM,YAAA,GAAA,MAAA,QAA2C,IAAI;CAErD,MAAM,gBAAA,GAAA,MAAA,cACH,UAAiB;EAChB,MAAM,SAAS,MAAM;EACrB,IAAI,QAAQ,OAAO;GACjB,SAAS,OAAO,KAAK;GACrB,QAAQ,WAAW,OAAO,KAAK;EACjC;CACF,GACA,CAAC,QAAQ,QAAQ,CACnB;CAEA,MAAM,uBAAA,GAAA,MAAA,mBAAwC;EAC5C,SAAS,SAAS,OAAO;EACzB,SAAS,UAAU,YAAY,OAAO;EAEtC,IAAI,SAAS,SAAS;GACpB,SAAS,QAAQ,iBAAiB,UAAU,cAAc,EAAE,MAAM,KAAK,CAAC;GACxE,IAAI,QAAQ,UACV,SAAS,QAAQ,iBAAiB,UAAU,QAAQ,UAAU,EAAE,MAAM,KAAK,CAAC;GAE9E,SAAS,KAAK,YAAY,SAAS,OAAO;EAC5C;CACF,GAAG,CAAC,SAAS,YAAY,CAAC;CAE1B,8BAAA,0BAA0B;EACxB,oBAAoB;EACpB,aAAa,SAAS,SAAS,OAAO;CACxC,GAAG,CAAC,CAAC;CAEL,MAAM,SAAA,GAAA,MAAA,mBAA0B;EAC9B,SAAS,IAAI;EACb,QAAQ,WAAW,IAAI;CACzB,GAAG,CAAC,QAAQ,QAAQ,CAAC;CAWrB,OAAO;EAAE;EAAO,OAAA,GAAA,MAAA,mBATe;GAC7B,IAAI,QAAQ,aACV,MAAM;GAGR,oBAAoB;GACpB,SAAS,SAAS,MAAM;EAC1B,GAAG;GAAC,QAAQ;GAAa;GAAO;EAAmB,CAEhC;EAAG;CAAM;AAC9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-floating-window.cjs","names":[],"sources":["../../src/use-floating-window/use-floating-window.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\nimport { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nfunction useRefValue<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\ninterface FloatingWindowPositionConfig {\n top?: number;\n left?: number;\n right?: number;\n bottom?: number;\n}\n\ninterface FloatingWindowPosition {\n /** Element offset from the left side of the viewport */\n x: number;\n\n /** Element offset from the top side of the viewport */\n y: number;\n}\n\nexport interface UseFloatingWindowOptions {\n /** If `false`, the element can not be dragged. */\n enabled?: boolean;\n\n /** If `true`, the element can only move within the current viewport boundaries. */\n constrainToViewport?: boolean;\n\n /** The offset from the viewport edges when constraining the element. Requires `constrainToViewport: true`. */\n constrainOffset?: number;\n\n /** Selector of an element that should be used to drag floating window. If not specified, the entire root element is used as a drag target. */\n dragHandleSelector?: string;\n\n /** Selector of an element within `dragHandleSelector` that should be excluded from the drag event. */\n excludeDragHandleSelector?: string;\n\n /** If set, restricts movement to the specified axis */\n axis?: 'x' | 'y';\n\n /** Initial position. If not set, calculated from element styles. */\n initialPosition?: FloatingWindowPositionConfig;\n\n /** Called when the element position changes */\n onPositionChange?: (pos: FloatingWindowPosition) => void;\n\n /** Called when the drag starts */\n onDragStart?: () => void;\n\n /** Called when the drag stops */\n onDragEnd?: () => void;\n}\n\nexport type SetFloatingWindowPosition = (position: FloatingWindowPositionConfig) => void;\n\nexport interface UseFloatingWindowReturnValue<T extends HTMLElement> {\n /** Ref to the element that should be draggable */\n ref: RefCallback<T | null>;\n\n /** Function to set the position of the element */\n setPosition: SetFloatingWindowPosition;\n\n /** `true` if the element is currently being dragged */\n isDragging: boolean;\n}\n\nexport function useFloatingWindow<T extends HTMLElement>(\n options: UseFloatingWindowOptions = {}\n): UseFloatingWindowReturnValue<T> {\n const [element, setElement] = useState<T | null>(null);\n const ref = useRef<T>(null);\n const pos = useRef({ x: 0, y: 0 });\n const offset = useRef({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const isDraggingRef = useRef(false);\n const initialized = useRef(false);\n const enabledRef = useRefValue(options.enabled);\n\n const setDragging = useCallback((value: boolean) => {\n setIsDragging(value);\n isDraggingRef.current = value;\n }, []);\n\n const assignRef = useCallback((node: T | null) => {\n if (node) {\n ref.current = node;\n setElement(node);\n } else {\n ref.current = null;\n setElement(null);\n }\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!initialized.current && el) {\n initialized.current = true;\n pos.current = calculateInitialPosition(el, options);\n el.style.left = `${pos.current.x}px`;\n el.style.top = `${pos.current.y}px`;\n el.style.right = 'unset';\n el.style.bottom = 'unset';\n }\n\n return () => {\n initialized.current = false;\n };\n }, [\n element,\n options.constrainOffset,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n options.constrainToViewport,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const controller = new AbortController();\n const signal = controller.signal;\n\n const onStart = (e: MouseEvent | TouchEvent) => {\n if (enabledRef.current === false) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n\n if ('button' in e && e.button !== 0) {\n return;\n }\n\n if (!getHandle(el, e.target, options)) {\n return;\n }\n\n setDragging(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n\n const rect = el.getBoundingClientRect();\n\n offset.current = {\n x: point.clientX - rect.left,\n y: point.clientY - rect.top,\n };\n\n options.onDragStart?.();\n\n document.addEventListener('mousemove', onMove, { signal });\n document.addEventListener('mouseup', onEnd, { signal });\n document.addEventListener('touchmove', onMove, { signal, passive: false });\n document.addEventListener('touchend', onEnd, { signal });\n };\n\n const onMove = (e: MouseEvent | TouchEvent) => {\n if (!isDraggingRef.current) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n e.preventDefault();\n\n let x = point.clientX - offset.current.x;\n let y = point.clientY - offset.current.y;\n\n const constrained = getConstrainedPosition(el, { x, y }, options);\n if (options.axis === 'x') {\n x = constrained.x;\n y = pos.current.y;\n } else if (options.axis === 'y') {\n x = pos.current.x;\n y = constrained.y;\n } else {\n x = constrained.x;\n y = constrained.y;\n }\n\n pos.current = { x, y };\n\n if (ref.current) {\n ref.current.style.left = `${x}px`;\n ref.current.style.top = `${y}px`;\n }\n\n options.onPositionChange?.({ x, y });\n };\n\n const onEnd = () => {\n if (isDraggingRef.current) {\n setDragging(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n options.onDragEnd?.();\n }\n };\n\n el.addEventListener('mousedown', onStart, { signal });\n el.addEventListener('touchstart', onStart, { signal, passive: false });\n\n return () => {\n controller.abort();\n };\n }, [\n options.constrainToViewport,\n options.constrainOffset,\n options.dragHandleSelector,\n options.axis,\n options.onPositionChange,\n options.onDragStart,\n options.onDragEnd,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n element,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const observer = new ResizeObserver(() => {\n // Re-clamp current position if element size changes\n const constrained = getConstrainedPosition(el, pos.current, options);\n pos.current = constrained;\n el.style.left = `${constrained.x}px`;\n el.style.top = `${constrained.y}px`;\n });\n\n observer.observe(el);\n\n return () => {\n observer.disconnect();\n };\n }, [options.constrainToViewport, options.constrainOffset]);\n\n const setPosition = useCallback(\n (position: FloatingWindowPositionConfig) => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const offset = options.constrainOffset ?? 0;\n const rect = el.getBoundingClientRect();\n\n let x: number | undefined;\n let y: number | undefined;\n\n if (position.left != null) {\n x = position.left;\n } else if (position.right != null) {\n x = window.innerWidth - rect.width - position.right;\n }\n\n if (position.top != null) {\n y = position.top;\n } else if (position.bottom != null) {\n y = window.innerHeight - rect.height - position.bottom;\n }\n\n x = x ?? pos.current.x;\n y = y ?? pos.current.y;\n\n if (options.constrainToViewport) {\n const clamped = clampToViewport(x, y, el, offset);\n x = clamped.x;\n y = clamped.y;\n }\n\n pos.current = { x, y };\n el.style.left = `${x}px`;\n el.style.top = `${y}px`;\n options.onPositionChange?.({ x, y });\n },\n [options.constrainToViewport, options.constrainOffset, options.onPositionChange]\n );\n\n return {\n ref: assignRef,\n setPosition,\n isDragging,\n };\n}\n\n// -------------------------------------------------------\n// Helper functions\n// -------------------------------------------------------\n\nfunction px(v: string) {\n return v.endsWith('px') ? parseFloat(v) : 0;\n}\n\nfunction calculateInitialPosition(\n el: HTMLElement,\n options: UseFloatingWindowOptions\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const winW = window.innerWidth;\n const winH = window.innerHeight;\n const style = window.getComputedStyle(el);\n const top = options.initialPosition?.top;\n const left = options.initialPosition?.left;\n const right = options.initialPosition?.right;\n const bottom = options.initialPosition?.bottom;\n\n let x = offset;\n let y = offset;\n\n if (left != null) {\n x = left;\n } else if (right != null) {\n x = winW - rect.width - right;\n } else {\n x = px(style.left) || winW - rect.width - px(style.right) || offset;\n }\n\n if (top != null) {\n y = top;\n } else if (bottom != null) {\n y = winH - rect.height - bottom;\n } else {\n y = px(style.top) || winH - rect.height - px(style.bottom) || offset;\n }\n\n return options.constrainToViewport\n ? clampToViewport(x, y, el, options.constrainOffset)\n : { x, y };\n}\n\nfunction getConstrainedPosition(\n el: HTMLElement,\n pos: FloatingWindowPosition,\n options: UseFloatingWindowOptions\n) {\n if (!options.constrainToViewport || !el) {\n return pos;\n }\n\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, pos.x), maxX),\n y: Math.min(Math.max(offset, pos.y), maxY),\n };\n}\n\nfunction matchesExcludeSelector(target: Node, excludeSelector?: string): boolean {\n if (!excludeSelector) {\n return false;\n }\n if (!(target instanceof Element)) {\n return false;\n }\n\n return Boolean(target.closest(excludeSelector));\n}\n\nfunction getHandle(\n el: HTMLElement,\n target: EventTarget | null,\n options: UseFloatingWindowOptions\n): boolean {\n if (!(target instanceof Node)) {\n return false;\n }\n\n // If no drag handle selector, allow dragging from entire element\n if (!options.dragHandleSelector) {\n return !matchesExcludeSelector(target, options.excludeDragHandleSelector);\n }\n\n const handles = Array.from(el.querySelectorAll(options.dragHandleSelector));\n return handles.some(\n (handle) =>\n handle.contains(target) && !matchesExcludeSelector(target, options.excludeDragHandleSelector)\n );\n}\n\nfunction clampToViewport(\n x: number,\n y: number,\n el: HTMLElement,\n offset: number = 0\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, x), maxX),\n y: Math.min(Math.max(offset, y), maxY),\n };\n}\n\nexport namespace useFloatingWindow {\n export type Options = UseFloatingWindowOptions;\n export type Position = FloatingWindowPosition;\n export type SetPosition = SetFloatingWindowPosition;\n export type ReturnValue<T extends HTMLElement> = UseFloatingWindowReturnValue<T>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-floating-window.cjs","names":[],"sources":["../../src/use-floating-window/use-floating-window.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\nimport { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nfunction useRefValue<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\ninterface FloatingWindowPositionConfig {\n top?: number;\n left?: number;\n right?: number;\n bottom?: number;\n}\n\ninterface FloatingWindowPosition {\n /** Element offset from the left side of the viewport */\n x: number;\n\n /** Element offset from the top side of the viewport */\n y: number;\n}\n\nexport interface UseFloatingWindowOptions {\n /** If `false`, the element can not be dragged. */\n enabled?: boolean;\n\n /** If `true`, the element can only move within the current viewport boundaries. */\n constrainToViewport?: boolean;\n\n /** The offset from the viewport edges when constraining the element. Requires `constrainToViewport: true`. */\n constrainOffset?: number;\n\n /** Selector of an element that should be used to drag floating window. If not specified, the entire root element is used as a drag target. */\n dragHandleSelector?: string;\n\n /** Selector of an element within `dragHandleSelector` that should be excluded from the drag event. */\n excludeDragHandleSelector?: string;\n\n /** If set, restricts movement to the specified axis */\n axis?: 'x' | 'y';\n\n /** Initial position. If not set, calculated from element styles. */\n initialPosition?: FloatingWindowPositionConfig;\n\n /** Called when the element position changes */\n onPositionChange?: (pos: FloatingWindowPosition) => void;\n\n /** Called when the drag starts */\n onDragStart?: () => void;\n\n /** Called when the drag stops */\n onDragEnd?: () => void;\n}\n\nexport type SetFloatingWindowPosition = (position: FloatingWindowPositionConfig) => void;\n\nexport interface UseFloatingWindowReturnValue<T extends HTMLElement> {\n /** Ref to the element that should be draggable */\n ref: RefCallback<T | null>;\n\n /** Function to set the position of the element */\n setPosition: SetFloatingWindowPosition;\n\n /** `true` if the element is currently being dragged */\n isDragging: boolean;\n}\n\nexport function useFloatingWindow<T extends HTMLElement>(\n options: UseFloatingWindowOptions = {}\n): UseFloatingWindowReturnValue<T> {\n const [element, setElement] = useState<T | null>(null);\n const ref = useRef<T>(null);\n const pos = useRef({ x: 0, y: 0 });\n const offset = useRef({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const isDraggingRef = useRef(false);\n const initialized = useRef(false);\n const enabledRef = useRefValue(options.enabled);\n\n const setDragging = useCallback((value: boolean) => {\n setIsDragging(value);\n isDraggingRef.current = value;\n }, []);\n\n const assignRef = useCallback((node: T | null) => {\n if (node) {\n ref.current = node;\n setElement(node);\n } else {\n ref.current = null;\n setElement(null);\n }\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!initialized.current && el) {\n initialized.current = true;\n pos.current = calculateInitialPosition(el, options);\n el.style.left = `${pos.current.x}px`;\n el.style.top = `${pos.current.y}px`;\n el.style.right = 'unset';\n el.style.bottom = 'unset';\n }\n\n return () => {\n initialized.current = false;\n };\n }, [\n element,\n options.constrainOffset,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n options.constrainToViewport,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const controller = new AbortController();\n const signal = controller.signal;\n\n const onStart = (e: MouseEvent | TouchEvent) => {\n if (enabledRef.current === false) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n\n if ('button' in e && e.button !== 0) {\n return;\n }\n\n if (!getHandle(el, e.target, options)) {\n return;\n }\n\n setDragging(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n\n const rect = el.getBoundingClientRect();\n\n offset.current = {\n x: point.clientX - rect.left,\n y: point.clientY - rect.top,\n };\n\n options.onDragStart?.();\n\n document.addEventListener('mousemove', onMove, { signal });\n document.addEventListener('mouseup', onEnd, { signal });\n document.addEventListener('touchmove', onMove, { signal, passive: false });\n document.addEventListener('touchend', onEnd, { signal });\n };\n\n const onMove = (e: MouseEvent | TouchEvent) => {\n if (!isDraggingRef.current) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n e.preventDefault();\n\n let x = point.clientX - offset.current.x;\n let y = point.clientY - offset.current.y;\n\n const constrained = getConstrainedPosition(el, { x, y }, options);\n if (options.axis === 'x') {\n x = constrained.x;\n y = pos.current.y;\n } else if (options.axis === 'y') {\n x = pos.current.x;\n y = constrained.y;\n } else {\n x = constrained.x;\n y = constrained.y;\n }\n\n pos.current = { x, y };\n\n if (ref.current) {\n ref.current.style.left = `${x}px`;\n ref.current.style.top = `${y}px`;\n }\n\n options.onPositionChange?.({ x, y });\n };\n\n const onEnd = () => {\n if (isDraggingRef.current) {\n setDragging(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n options.onDragEnd?.();\n }\n };\n\n el.addEventListener('mousedown', onStart, { signal });\n el.addEventListener('touchstart', onStart, { signal, passive: false });\n\n return () => {\n controller.abort();\n };\n }, [\n options.constrainToViewport,\n options.constrainOffset,\n options.dragHandleSelector,\n options.axis,\n options.onPositionChange,\n options.onDragStart,\n options.onDragEnd,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n element,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const observer = new ResizeObserver(() => {\n // Re-clamp current position if element size changes\n const constrained = getConstrainedPosition(el, pos.current, options);\n pos.current = constrained;\n el.style.left = `${constrained.x}px`;\n el.style.top = `${constrained.y}px`;\n });\n\n observer.observe(el);\n\n return () => {\n observer.disconnect();\n };\n }, [options.constrainToViewport, options.constrainOffset]);\n\n const setPosition = useCallback(\n (position: FloatingWindowPositionConfig) => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const offset = options.constrainOffset ?? 0;\n const rect = el.getBoundingClientRect();\n\n let x: number | undefined;\n let y: number | undefined;\n\n if (position.left != null) {\n x = position.left;\n } else if (position.right != null) {\n x = window.innerWidth - rect.width - position.right;\n }\n\n if (position.top != null) {\n y = position.top;\n } else if (position.bottom != null) {\n y = window.innerHeight - rect.height - position.bottom;\n }\n\n x = x ?? pos.current.x;\n y = y ?? pos.current.y;\n\n if (options.constrainToViewport) {\n const clamped = clampToViewport(x, y, el, offset);\n x = clamped.x;\n y = clamped.y;\n }\n\n pos.current = { x, y };\n el.style.left = `${x}px`;\n el.style.top = `${y}px`;\n options.onPositionChange?.({ x, y });\n },\n [options.constrainToViewport, options.constrainOffset, options.onPositionChange]\n );\n\n return {\n ref: assignRef,\n setPosition,\n isDragging,\n };\n}\n\n// -------------------------------------------------------\n// Helper functions\n// -------------------------------------------------------\n\nfunction px(v: string) {\n return v.endsWith('px') ? parseFloat(v) : 0;\n}\n\nfunction calculateInitialPosition(\n el: HTMLElement,\n options: UseFloatingWindowOptions\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const winW = window.innerWidth;\n const winH = window.innerHeight;\n const style = window.getComputedStyle(el);\n const top = options.initialPosition?.top;\n const left = options.initialPosition?.left;\n const right = options.initialPosition?.right;\n const bottom = options.initialPosition?.bottom;\n\n let x = offset;\n let y = offset;\n\n if (left != null) {\n x = left;\n } else if (right != null) {\n x = winW - rect.width - right;\n } else {\n x = px(style.left) || winW - rect.width - px(style.right) || offset;\n }\n\n if (top != null) {\n y = top;\n } else if (bottom != null) {\n y = winH - rect.height - bottom;\n } else {\n y = px(style.top) || winH - rect.height - px(style.bottom) || offset;\n }\n\n return options.constrainToViewport\n ? clampToViewport(x, y, el, options.constrainOffset)\n : { x, y };\n}\n\nfunction getConstrainedPosition(\n el: HTMLElement,\n pos: FloatingWindowPosition,\n options: UseFloatingWindowOptions\n) {\n if (!options.constrainToViewport || !el) {\n return pos;\n }\n\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, pos.x), maxX),\n y: Math.min(Math.max(offset, pos.y), maxY),\n };\n}\n\nfunction matchesExcludeSelector(target: Node, excludeSelector?: string): boolean {\n if (!excludeSelector) {\n return false;\n }\n if (!(target instanceof Element)) {\n return false;\n }\n\n return Boolean(target.closest(excludeSelector));\n}\n\nfunction getHandle(\n el: HTMLElement,\n target: EventTarget | null,\n options: UseFloatingWindowOptions\n): boolean {\n if (!(target instanceof Node)) {\n return false;\n }\n\n // If no drag handle selector, allow dragging from entire element\n if (!options.dragHandleSelector) {\n return !matchesExcludeSelector(target, options.excludeDragHandleSelector);\n }\n\n const handles = Array.from(el.querySelectorAll(options.dragHandleSelector));\n return handles.some(\n (handle) =>\n handle.contains(target) && !matchesExcludeSelector(target, options.excludeDragHandleSelector)\n );\n}\n\nfunction clampToViewport(\n x: number,\n y: number,\n el: HTMLElement,\n offset: number = 0\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, x), maxX),\n y: Math.min(Math.max(offset, y), maxY),\n };\n}\n\nexport namespace useFloatingWindow {\n export type Options = UseFloatingWindowOptions;\n export type Position = FloatingWindowPosition;\n export type SetPosition = SetFloatingWindowPosition;\n export type ReturnValue<T extends HTMLElement> = UseFloatingWindowReturnValue<T>;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-focus-return.cjs","names":[],"sources":["../../src/use-focus-return/use-focus-return.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\n\nexport interface UseFocusReturnInput {\n opened: boolean;\n shouldReturnFocus?: boolean;\n}\n\nexport type UseFocusReturnReturnValue = () => void;\n\nexport function useFocusReturn({\n opened,\n shouldReturnFocus = true,\n}: UseFocusReturnInput): UseFocusReturnReturnValue {\n const lastActiveElement = useRef<HTMLElement>(null);\n const returnFocus = () => {\n if (\n lastActiveElement.current &&\n 'focus' in lastActiveElement.current &&\n typeof lastActiveElement.current.focus === 'function'\n ) {\n lastActiveElement.current?.focus({ preventScroll: true });\n }\n };\n\n useDidUpdate(() => {\n let timeout = -1;\n\n const clearFocusTimeout = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n window.clearTimeout(timeout);\n }\n };\n\n document.addEventListener('keydown', clearFocusTimeout);\n\n if (opened) {\n lastActiveElement.current = document.activeElement as HTMLElement;\n } else if (shouldReturnFocus) {\n const activeElementAtClose = document.activeElement;\n timeout = window.setTimeout(() => {\n const currentActiveElement = document.activeElement;\n if (\n currentActiveElement === null ||\n currentActiveElement === document.body ||\n currentActiveElement === activeElementAtClose\n ) {\n returnFocus();\n }\n }, 10);\n }\n\n return () => {\n window.clearTimeout(timeout);\n document.removeEventListener('keydown', clearFocusTimeout);\n };\n }, [opened, shouldReturnFocus]);\n\n return returnFocus;\n}\n\nexport namespace useFocusReturn {\n export type Input = UseFocusReturnInput;\n export type ReturnValue = UseFocusReturnReturnValue;\n}\n"],"mappings":";;;;AAUA,SAAgB,eAAe,EAC7B,QACA,oBAAoB,QAC6B;CACjD,MAAM,qBAAA,GAAA,MAAA,QAAwC,
|
|
1
|
+
{"version":3,"file":"use-focus-return.cjs","names":[],"sources":["../../src/use-focus-return/use-focus-return.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\n\nexport interface UseFocusReturnInput {\n opened: boolean;\n shouldReturnFocus?: boolean;\n}\n\nexport type UseFocusReturnReturnValue = () => void;\n\nexport function useFocusReturn({\n opened,\n shouldReturnFocus = true,\n}: UseFocusReturnInput): UseFocusReturnReturnValue {\n const lastActiveElement = useRef<HTMLElement>(null);\n const returnFocus = () => {\n if (\n lastActiveElement.current &&\n 'focus' in lastActiveElement.current &&\n typeof lastActiveElement.current.focus === 'function'\n ) {\n lastActiveElement.current?.focus({ preventScroll: true });\n }\n };\n\n useDidUpdate(() => {\n let timeout = -1;\n\n const clearFocusTimeout = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n window.clearTimeout(timeout);\n }\n };\n\n document.addEventListener('keydown', clearFocusTimeout);\n\n if (opened) {\n lastActiveElement.current = document.activeElement as HTMLElement;\n } else if (shouldReturnFocus) {\n const activeElementAtClose = document.activeElement;\n timeout = window.setTimeout(() => {\n const currentActiveElement = document.activeElement;\n if (\n currentActiveElement === null ||\n currentActiveElement === document.body ||\n currentActiveElement === activeElementAtClose\n ) {\n returnFocus();\n }\n }, 10);\n }\n\n return () => {\n window.clearTimeout(timeout);\n document.removeEventListener('keydown', clearFocusTimeout);\n };\n }, [opened, shouldReturnFocus]);\n\n return returnFocus;\n}\n\nexport namespace useFocusReturn {\n export type Input = UseFocusReturnInput;\n export type ReturnValue = UseFocusReturnReturnValue;\n}\n"],"mappings":";;;;AAUA,SAAgB,eAAe,EAC7B,QACA,oBAAoB,QAC6B;CACjD,MAAM,qBAAA,GAAA,MAAA,QAAwC,IAAI;CAClD,MAAM,oBAAoB;EACxB,IACE,kBAAkB,WAClB,WAAW,kBAAkB,WAC7B,OAAO,kBAAkB,QAAQ,UAAU,YAE3C,kBAAkB,SAAS,MAAM,EAAE,eAAe,KAAK,CAAC;CAE5D;CAEA,uBAAA,mBAAmB;EACjB,IAAI,UAAU;EAEd,MAAM,qBAAqB,UAAyB;GAClD,IAAI,MAAM,QAAQ,OAChB,OAAO,aAAa,OAAO;EAE/B;EAEA,SAAS,iBAAiB,WAAW,iBAAiB;EAEtD,IAAI,QACF,kBAAkB,UAAU,SAAS;OAChC,IAAI,mBAAmB;GAC5B,MAAM,uBAAuB,SAAS;GACtC,UAAU,OAAO,iBAAiB;IAChC,MAAM,uBAAuB,SAAS;IACtC,IACE,yBAAyB,QACzB,yBAAyB,SAAS,QAClC,yBAAyB,sBAEzB,YAAY;GAEhB,GAAG,EAAE;EACP;EAEA,aAAa;GACX,OAAO,aAAa,OAAO;GAC3B,SAAS,oBAAoB,WAAW,iBAAiB;EAC3D;CACF,GAAG,CAAC,QAAQ,iBAAiB,CAAC;CAE9B,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-tab.cjs","names":["findTabbableDescendants"],"sources":["../../src/use-focus-trap/scope-tab.ts"],"sourcesContent":["import { findTabbableDescendants } from './tabbable';\n\nexport function scopeTab(node: HTMLElement, event: KeyboardEvent) {\n const tabbable = findTabbableDescendants(node);\n if (!tabbable.length) {\n event.preventDefault();\n return;\n }\n const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];\n const root = node.getRootNode() as unknown as DocumentOrShadowRoot;\n let leavingFinalTabbable = finalTabbable === root.activeElement || node === root.activeElement;\n\n const activeElement = root.activeElement as Element;\n const activeElementIsRadio =\n activeElement.tagName === 'INPUT' && activeElement.getAttribute('type') === 'radio';\n if (activeElementIsRadio) {\n const activeRadioGroup = tabbable.filter(\n (element) =>\n element.getAttribute('type') === 'radio' &&\n element.getAttribute('name') === activeElement.getAttribute('name')\n );\n leavingFinalTabbable = activeRadioGroup.includes(finalTabbable);\n }\n\n if (!leavingFinalTabbable) {\n return;\n }\n\n event.preventDefault();\n\n const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0];\n\n if (target) {\n target.focus();\n }\n}\n"],"mappings":";;;AAEA,SAAgB,SAAS,MAAmB,OAAsB;CAChE,MAAM,WAAWA,iBAAAA,wBAAwB,
|
|
1
|
+
{"version":3,"file":"scope-tab.cjs","names":["findTabbableDescendants"],"sources":["../../src/use-focus-trap/scope-tab.ts"],"sourcesContent":["import { findTabbableDescendants } from './tabbable';\n\nexport function scopeTab(node: HTMLElement, event: KeyboardEvent) {\n const tabbable = findTabbableDescendants(node);\n if (!tabbable.length) {\n event.preventDefault();\n return;\n }\n const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];\n const root = node.getRootNode() as unknown as DocumentOrShadowRoot;\n let leavingFinalTabbable = finalTabbable === root.activeElement || node === root.activeElement;\n\n const activeElement = root.activeElement as Element;\n const activeElementIsRadio =\n activeElement.tagName === 'INPUT' && activeElement.getAttribute('type') === 'radio';\n if (activeElementIsRadio) {\n const activeRadioGroup = tabbable.filter(\n (element) =>\n element.getAttribute('type') === 'radio' &&\n element.getAttribute('name') === activeElement.getAttribute('name')\n );\n leavingFinalTabbable = activeRadioGroup.includes(finalTabbable);\n }\n\n if (!leavingFinalTabbable) {\n return;\n }\n\n event.preventDefault();\n\n const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0];\n\n if (target) {\n target.focus();\n }\n}\n"],"mappings":";;;AAEA,SAAgB,SAAS,MAAmB,OAAsB;CAChE,MAAM,WAAWA,iBAAAA,wBAAwB,IAAI;CAC7C,IAAI,CAAC,SAAS,QAAQ;EACpB,MAAM,eAAe;EACrB;CACF;CACA,MAAM,gBAAgB,SAAS,MAAM,WAAW,IAAI,SAAS,SAAS;CACtE,MAAM,OAAO,KAAK,YAAY;CAC9B,IAAI,uBAAuB,kBAAkB,KAAK,iBAAiB,SAAS,KAAK;CAEjF,MAAM,gBAAgB,KAAK;CAG3B,IADE,cAAc,YAAY,WAAW,cAAc,aAAa,MAAM,MAAM,SAO5E,uBALyB,SAAS,QAC/B,YACC,QAAQ,aAAa,MAAM,MAAM,WACjC,QAAQ,aAAa,MAAM,MAAM,cAAc,aAAa,MAAM,CAEhC,EAAE,SAAS,aAAa;CAGhE,IAAI,CAAC,sBACH;CAGF,MAAM,eAAe;CAErB,MAAM,SAAS,SAAS,MAAM,WAAW,SAAS,SAAS,IAAI;CAE/D,IAAI,QACF,OAAO,MAAM;AAEjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabbable.cjs","names":[],"sources":["../../src/use-focus-trap/tabbable.ts"],"sourcesContent":["const TABBABLE_NODES = /input|select|textarea|button|object/;\nexport const FOCUS_SELECTOR = 'a, input, select, textarea, button, object, [tabindex]';\n\nfunction hidden(element: HTMLElement) {\n if (process.env.NODE_ENV === 'test') {\n return false;\n }\n\n return element.style.display === 'none';\n}\n\nfunction visible(element: HTMLElement) {\n const isHidden =\n element.getAttribute('aria-hidden') ||\n element.getAttribute('hidden') ||\n element.getAttribute('type') === 'hidden';\n\n if (isHidden) {\n return false;\n }\n\n let parentElement: HTMLElement = element;\n while (parentElement) {\n if (parentElement === document.body || parentElement.nodeType === 11) {\n break;\n }\n\n if (hidden(parentElement)) {\n return false;\n }\n\n parentElement = parentElement.parentNode as HTMLElement;\n }\n\n return true;\n}\n\nfunction getElementTabIndex(element: HTMLElement) {\n let tabIndex: string | null | undefined = element.getAttribute('tabindex');\n if (tabIndex === null) {\n tabIndex = undefined;\n }\n return parseInt(tabIndex as string, 10);\n}\n\nexport function focusable(element: HTMLElement) {\n const nodeName = element.nodeName.toLowerCase();\n const isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element));\n const res =\n // @ts-expect-error function accepts any html element but if it is a button, it should not be disabled to trigger the condition\n (TABBABLE_NODES.test(nodeName) && !element.disabled) ||\n (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN);\n\n return res && visible(element);\n}\n\nexport function tabbable(element: HTMLElement) {\n const tabIndex = getElementTabIndex(element);\n const isTabIndexNaN = Number.isNaN(tabIndex);\n return (isTabIndexNaN || tabIndex >= 0) && focusable(element);\n}\n\nexport function findTabbableDescendants(element: HTMLElement): HTMLElement[] {\n return Array.from(element.querySelectorAll<HTMLElement>(FOCUS_SELECTOR)).filter(tabbable);\n}\n"],"mappings":";;AAAA,MAAM,iBAAiB;AACvB,MAAa,iBAAiB;AAE9B,SAAS,OAAO,SAAsB;
|
|
1
|
+
{"version":3,"file":"tabbable.cjs","names":[],"sources":["../../src/use-focus-trap/tabbable.ts"],"sourcesContent":["const TABBABLE_NODES = /input|select|textarea|button|object/;\nexport const FOCUS_SELECTOR = 'a, input, select, textarea, button, object, [tabindex]';\n\nfunction hidden(element: HTMLElement) {\n if (process.env.NODE_ENV === 'test') {\n return false;\n }\n\n return element.style.display === 'none';\n}\n\nfunction visible(element: HTMLElement) {\n const isHidden =\n element.getAttribute('aria-hidden') ||\n element.getAttribute('hidden') ||\n element.getAttribute('type') === 'hidden';\n\n if (isHidden) {\n return false;\n }\n\n let parentElement: HTMLElement = element;\n while (parentElement) {\n if (parentElement === document.body || parentElement.nodeType === 11) {\n break;\n }\n\n if (hidden(parentElement)) {\n return false;\n }\n\n parentElement = parentElement.parentNode as HTMLElement;\n }\n\n return true;\n}\n\nfunction getElementTabIndex(element: HTMLElement) {\n let tabIndex: string | null | undefined = element.getAttribute('tabindex');\n if (tabIndex === null) {\n tabIndex = undefined;\n }\n return parseInt(tabIndex as string, 10);\n}\n\nexport function focusable(element: HTMLElement) {\n const nodeName = element.nodeName.toLowerCase();\n const isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element));\n const res =\n // @ts-expect-error function accepts any html element but if it is a button, it should not be disabled to trigger the condition\n (TABBABLE_NODES.test(nodeName) && !element.disabled) ||\n (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN);\n\n return res && visible(element);\n}\n\nexport function tabbable(element: HTMLElement) {\n const tabIndex = getElementTabIndex(element);\n const isTabIndexNaN = Number.isNaN(tabIndex);\n return (isTabIndexNaN || tabIndex >= 0) && focusable(element);\n}\n\nexport function findTabbableDescendants(element: HTMLElement): HTMLElement[] {\n return Array.from(element.querySelectorAll<HTMLElement>(FOCUS_SELECTOR)).filter(tabbable);\n}\n"],"mappings":";;AAAA,MAAM,iBAAiB;AACvB,MAAa,iBAAiB;AAE9B,SAAS,OAAO,SAAsB;CACpC,IAAI,QAAQ,IAAI,aAAa,QAC3B,OAAO;CAGT,OAAO,QAAQ,MAAM,YAAY;AACnC;AAEA,SAAS,QAAQ,SAAsB;CAMrC,IAJE,QAAQ,aAAa,aAAa,KAClC,QAAQ,aAAa,QAAQ,KAC7B,QAAQ,aAAa,MAAM,MAAM,UAGjC,OAAO;CAGT,IAAI,gBAA6B;CACjC,OAAO,eAAe;EACpB,IAAI,kBAAkB,SAAS,QAAQ,cAAc,aAAa,IAChE;EAGF,IAAI,OAAO,aAAa,GACtB,OAAO;EAGT,gBAAgB,cAAc;CAChC;CAEA,OAAO;AACT;AAEA,SAAS,mBAAmB,SAAsB;CAChD,IAAI,WAAsC,QAAQ,aAAa,UAAU;CACzE,IAAI,aAAa,MACf,WAAW,KAAA;CAEb,OAAO,SAAS,UAAoB,EAAE;AACxC;AAEA,SAAgB,UAAU,SAAsB;CAC9C,MAAM,WAAW,QAAQ,SAAS,YAAY;CAC9C,MAAM,mBAAmB,CAAC,OAAO,MAAM,mBAAmB,OAAO,CAAC;CAMlE,QAHG,eAAe,KAAK,QAAQ,KAAK,CAAC,QAAQ,aAC1C,mBAAmB,oBAAoB,QAAQ,QAAQ,mBAAmB,sBAE/D,QAAQ,OAAO;AAC/B;AAEA,SAAgB,SAAS,SAAsB;CAC7C,MAAM,WAAW,mBAAmB,OAAO;CAE3C,QADsB,OAAO,MAAM,QACf,KAAK,YAAY,MAAM,UAAU,OAAO;AAC9D;AAEA,SAAgB,wBAAwB,SAAqC;CAC3E,OAAO,MAAM,KAAK,QAAQ,iBAA8B,cAAc,CAAC,EAAE,OAAO,QAAQ;AAC1F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-focus-trap.cjs","names":["FOCUS_SELECTOR","tabbable","focusable"],"sources":["../../src/use-focus-trap/use-focus-trap.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { scopeTab } from './scope-tab';\nimport { FOCUS_SELECTOR, focusable, tabbable } from './tabbable';\n\nexport function useFocusTrap(active = true): React.RefCallback<HTMLElement | null> {\n const ref = useRef<HTMLElement>(null);\n\n const focusNode = (node: HTMLElement) => {\n let focusElement: HTMLElement | null = node.querySelector('[data-autofocus]');\n\n if (!focusElement) {\n const children = Array.from<HTMLElement>(node.querySelectorAll(FOCUS_SELECTOR));\n focusElement = children.find(tabbable) || children.find(focusable) || null;\n if (!focusElement && focusable(node)) {\n focusElement = node;\n }\n }\n\n if (focusElement) {\n focusElement.focus({ preventScroll: true });\n } else if (process.env.NODE_ENV === 'development') {\n // oxlint-disable-next-line no-console\n console.warn(\n '[@mantine/hooks/use-focus-trap] Failed to find focusable element within provided node',\n node\n );\n }\n };\n\n const setRef = useCallback(\n (node: HTMLElement | null) => {\n if (!active) {\n return;\n }\n\n if (node === null) {\n ref.current = null;\n return;\n }\n\n if (ref.current === node) {\n return;\n }\n\n // Delay processing the HTML node by a frame. This ensures focus is assigned correctly.\n setTimeout(() => {\n if (node.getRootNode()) {\n focusNode(node);\n } else if (process.env.NODE_ENV === 'development') {\n // oxlint-disable-next-line no-console\n console.warn('[@mantine/hooks/use-focus-trap] Ref node is not part of the dom', node);\n }\n });\n\n ref.current = node;\n },\n [active]\n );\n\n useEffect(() => {\n if (!active) {\n return undefined;\n }\n\n if (ref.current) {\n setTimeout(() => {\n if (ref.current) {\n focusNode(ref.current);\n }\n });\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Tab' && ref.current) {\n scopeTab(ref.current, event);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [active]);\n\n return setRef;\n}\n"],"mappings":";;;;;AAIA,SAAgB,aAAa,SAAS,MAA6C;CACjF,MAAM,OAAA,GAAA,MAAA,QAA0B,
|
|
1
|
+
{"version":3,"file":"use-focus-trap.cjs","names":["FOCUS_SELECTOR","tabbable","focusable"],"sources":["../../src/use-focus-trap/use-focus-trap.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { scopeTab } from './scope-tab';\nimport { FOCUS_SELECTOR, focusable, tabbable } from './tabbable';\n\nexport function useFocusTrap(active = true): React.RefCallback<HTMLElement | null> {\n const ref = useRef<HTMLElement>(null);\n\n const focusNode = (node: HTMLElement) => {\n let focusElement: HTMLElement | null = node.querySelector('[data-autofocus]');\n\n if (!focusElement) {\n const children = Array.from<HTMLElement>(node.querySelectorAll(FOCUS_SELECTOR));\n focusElement = children.find(tabbable) || children.find(focusable) || null;\n if (!focusElement && focusable(node)) {\n focusElement = node;\n }\n }\n\n if (focusElement) {\n focusElement.focus({ preventScroll: true });\n } else if (process.env.NODE_ENV === 'development') {\n // oxlint-disable-next-line no-console\n console.warn(\n '[@mantine/hooks/use-focus-trap] Failed to find focusable element within provided node',\n node\n );\n }\n };\n\n const setRef = useCallback(\n (node: HTMLElement | null) => {\n if (!active) {\n return;\n }\n\n if (node === null) {\n ref.current = null;\n return;\n }\n\n if (ref.current === node) {\n return;\n }\n\n // Delay processing the HTML node by a frame. This ensures focus is assigned correctly.\n setTimeout(() => {\n if (node.getRootNode()) {\n focusNode(node);\n } else if (process.env.NODE_ENV === 'development') {\n // oxlint-disable-next-line no-console\n console.warn('[@mantine/hooks/use-focus-trap] Ref node is not part of the dom', node);\n }\n });\n\n ref.current = node;\n },\n [active]\n );\n\n useEffect(() => {\n if (!active) {\n return undefined;\n }\n\n if (ref.current) {\n setTimeout(() => {\n if (ref.current) {\n focusNode(ref.current);\n }\n });\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Tab' && ref.current) {\n scopeTab(ref.current, event);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [active]);\n\n return setRef;\n}\n"],"mappings":";;;;;AAIA,SAAgB,aAAa,SAAS,MAA6C;CACjF,MAAM,OAAA,GAAA,MAAA,QAA0B,IAAI;CAEpC,MAAM,aAAa,SAAsB;EACvC,IAAI,eAAmC,KAAK,cAAc,kBAAkB;EAE5E,IAAI,CAAC,cAAc;GACjB,MAAM,WAAW,MAAM,KAAkB,KAAK,iBAAiBA,iBAAAA,cAAc,CAAC;GAC9E,eAAe,SAAS,KAAKC,iBAAAA,QAAQ,KAAK,SAAS,KAAKC,iBAAAA,SAAS,KAAK;GACtE,IAAI,CAAC,gBAAgBA,iBAAAA,UAAU,IAAI,GACjC,eAAe;EAEnB;EAEA,IAAI,cACF,aAAa,MAAM,EAAE,eAAe,KAAK,CAAC;OACrC,IAAI,QAAQ,IAAI,aAAa,eAElC,QAAQ,KACN,yFACA,IACF;CAEJ;CAEA,MAAM,UAAA,GAAA,MAAA,cACH,SAA6B;EAC5B,IAAI,CAAC,QACH;EAGF,IAAI,SAAS,MAAM;GACjB,IAAI,UAAU;GACd;EACF;EAEA,IAAI,IAAI,YAAY,MAClB;EAIF,iBAAiB;GACf,IAAI,KAAK,YAAY,GACnB,UAAU,IAAI;QACT,IAAI,QAAQ,IAAI,aAAa,eAElC,QAAQ,KAAK,mEAAmE,IAAI;EAExF,CAAC;EAED,IAAI,UAAU;CAChB,GACA,CAAC,MAAM,CACT;CAEA,CAAA,GAAA,MAAA,iBAAgB;EACd,IAAI,CAAC,QACH;EAGF,IAAI,IAAI,SACN,iBAAiB;GACf,IAAI,IAAI,SACN,UAAU,IAAI,OAAO;EAEzB,CAAC;EAGH,MAAM,iBAAiB,UAAyB;GAC9C,IAAI,MAAM,QAAQ,SAAS,IAAI,SAC7B,kBAAA,SAAS,IAAI,SAAS,KAAK;EAE/B;EAEA,SAAS,iBAAiB,WAAW,aAAa;EAClD,aAAa,SAAS,oBAAoB,WAAW,aAAa;CACpE,GAAG,CAAC,MAAM,CAAC;CAEX,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-focus-within.cjs","names":["useCallbackRef"],"sources":["../../src/use-focus-within/use-focus-within.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useCallbackRef } from '../utils';\n\nfunction containsRelatedTarget(event: FocusEvent) {\n if (event.currentTarget instanceof HTMLElement && event.relatedTarget instanceof HTMLElement) {\n return event.currentTarget.contains(event.relatedTarget);\n }\n\n return false;\n}\n\nexport interface UseFocusWithinOptions {\n onFocus?: (event: FocusEvent) => void;\n onBlur?: (event: FocusEvent) => void;\n}\n\nexport interface UseFocusWithinReturnValue<T extends HTMLElement = any> {\n ref: React.RefCallback<T | null>;\n focused: boolean;\n}\n\nexport function useFocusWithin<T extends HTMLElement = any>({\n onBlur,\n onFocus,\n}: UseFocusWithinOptions = {}): UseFocusWithinReturnValue<T> {\n const [focused, setFocused] = useState(false);\n const focusedRef = useRef(false);\n const previousNode = useRef<T | null>(null);\n\n const onFocusRef = useCallbackRef(onFocus);\n const onBlurRef = useCallbackRef(onBlur);\n\n const _setFocused = useCallback((value: boolean) => {\n setFocused(value);\n focusedRef.current = value;\n }, []);\n\n const handleFocusIn = useCallback((event: FocusEvent) => {\n if (!focusedRef.current) {\n _setFocused(true);\n onFocusRef(event);\n }\n }, []);\n\n const handleFocusOut = useCallback((event: FocusEvent) => {\n if (focusedRef.current && !containsRelatedTarget(event)) {\n _setFocused(false);\n onBlurRef(event);\n }\n }, []);\n\n const callbackRef: React.RefCallback<T | null> = useCallback(\n (node) => {\n if (!node) {\n return;\n }\n\n if (previousNode.current) {\n previousNode.current.removeEventListener('focusin', handleFocusIn);\n previousNode.current.removeEventListener('focusout', handleFocusOut);\n }\n\n node.addEventListener('focusin', handleFocusIn);\n node.addEventListener('focusout', handleFocusOut);\n previousNode.current = node;\n },\n [handleFocusIn, handleFocusOut]\n );\n\n useEffect(\n () => () => {\n if (previousNode.current) {\n previousNode.current.removeEventListener('focusin', handleFocusIn);\n previousNode.current.removeEventListener('focusout', handleFocusOut);\n }\n },\n []\n );\n\n return { ref: callbackRef, focused };\n}\n\nexport namespace useFocusWithin {\n export type Options = UseFocusWithinOptions;\n export type ReturnValue<T extends HTMLElement> = UseFocusWithinReturnValue<T>;\n}\n"],"mappings":";;;;AAGA,SAAS,sBAAsB,OAAmB;
|
|
1
|
+
{"version":3,"file":"use-focus-within.cjs","names":["useCallbackRef"],"sources":["../../src/use-focus-within/use-focus-within.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useCallbackRef } from '../utils';\n\nfunction containsRelatedTarget(event: FocusEvent) {\n if (event.currentTarget instanceof HTMLElement && event.relatedTarget instanceof HTMLElement) {\n return event.currentTarget.contains(event.relatedTarget);\n }\n\n return false;\n}\n\nexport interface UseFocusWithinOptions {\n onFocus?: (event: FocusEvent) => void;\n onBlur?: (event: FocusEvent) => void;\n}\n\nexport interface UseFocusWithinReturnValue<T extends HTMLElement = any> {\n ref: React.RefCallback<T | null>;\n focused: boolean;\n}\n\nexport function useFocusWithin<T extends HTMLElement = any>({\n onBlur,\n onFocus,\n}: UseFocusWithinOptions = {}): UseFocusWithinReturnValue<T> {\n const [focused, setFocused] = useState(false);\n const focusedRef = useRef(false);\n const previousNode = useRef<T | null>(null);\n\n const onFocusRef = useCallbackRef(onFocus);\n const onBlurRef = useCallbackRef(onBlur);\n\n const _setFocused = useCallback((value: boolean) => {\n setFocused(value);\n focusedRef.current = value;\n }, []);\n\n const handleFocusIn = useCallback((event: FocusEvent) => {\n if (!focusedRef.current) {\n _setFocused(true);\n onFocusRef(event);\n }\n }, []);\n\n const handleFocusOut = useCallback((event: FocusEvent) => {\n if (focusedRef.current && !containsRelatedTarget(event)) {\n _setFocused(false);\n onBlurRef(event);\n }\n }, []);\n\n const callbackRef: React.RefCallback<T | null> = useCallback(\n (node) => {\n if (!node) {\n return;\n }\n\n if (previousNode.current) {\n previousNode.current.removeEventListener('focusin', handleFocusIn);\n previousNode.current.removeEventListener('focusout', handleFocusOut);\n }\n\n node.addEventListener('focusin', handleFocusIn);\n node.addEventListener('focusout', handleFocusOut);\n previousNode.current = node;\n },\n [handleFocusIn, handleFocusOut]\n );\n\n useEffect(\n () => () => {\n if (previousNode.current) {\n previousNode.current.removeEventListener('focusin', handleFocusIn);\n previousNode.current.removeEventListener('focusout', handleFocusOut);\n }\n },\n []\n );\n\n return { ref: callbackRef, focused };\n}\n\nexport namespace useFocusWithin {\n export type Options = UseFocusWithinOptions;\n export type ReturnValue<T extends HTMLElement> = UseFocusWithinReturnValue<T>;\n}\n"],"mappings":";;;;AAGA,SAAS,sBAAsB,OAAmB;CAChD,IAAI,MAAM,yBAAyB,eAAe,MAAM,yBAAyB,aAC/E,OAAO,MAAM,cAAc,SAAS,MAAM,aAAa;CAGzD,OAAO;AACT;AAYA,SAAgB,eAA4C,EAC1D,QACA,YACyB,CAAC,GAAiC;CAC3D,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,UAAuB,KAAK;CAC5C,MAAM,cAAA,GAAA,MAAA,QAAoB,KAAK;CAC/B,MAAM,gBAAA,GAAA,MAAA,QAAgC,IAAI;CAE1C,MAAM,aAAaA,yBAAAA,eAAe,OAAO;CACzC,MAAM,YAAYA,yBAAAA,eAAe,MAAM;CAEvC,MAAM,eAAA,GAAA,MAAA,cAA2B,UAAmB;EAClD,WAAW,KAAK;EAChB,WAAW,UAAU;CACvB,GAAG,CAAC,CAAC;CAEL,MAAM,iBAAA,GAAA,MAAA,cAA6B,UAAsB;EACvD,IAAI,CAAC,WAAW,SAAS;GACvB,YAAY,IAAI;GAChB,WAAW,KAAK;EAClB;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,kBAAA,GAAA,MAAA,cAA8B,UAAsB;EACxD,IAAI,WAAW,WAAW,CAAC,sBAAsB,KAAK,GAAG;GACvD,YAAY,KAAK;GACjB,UAAU,KAAK;EACjB;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,eAAA,GAAA,MAAA,cACH,SAAS;EACR,IAAI,CAAC,MACH;EAGF,IAAI,aAAa,SAAS;GACxB,aAAa,QAAQ,oBAAoB,WAAW,aAAa;GACjE,aAAa,QAAQ,oBAAoB,YAAY,cAAc;EACrE;EAEA,KAAK,iBAAiB,WAAW,aAAa;EAC9C,KAAK,iBAAiB,YAAY,cAAc;EAChD,aAAa,UAAU;CACzB,GACA,CAAC,eAAe,cAAc,CAChC;CAEA,CAAA,GAAA,MAAA,uBACc;EACV,IAAI,aAAa,SAAS;GACxB,aAAa,QAAQ,oBAAoB,WAAW,aAAa;GACjE,aAAa,QAAQ,oBAAoB,YAAY,cAAc;EACrE;CACF,GACA,CAAC,CACH;CAEA,OAAO;EAAE,KAAK;EAAa;CAAQ;AACrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-force-update.cjs","names":[],"sources":["../../src/use-force-update/use-force-update.ts"],"sourcesContent":["import { useReducer } from 'react';\n\nconst reducer = (value: number) => (value + 1) % 1000000;\n\nexport function useForceUpdate(): () => void {\n const [, update] = useReducer(reducer, 0);\n return update;\n}\n"],"mappings":";;;AAEA,MAAM,WAAW,WAAmB,QAAQ,KAAK;AAEjD,SAAgB,iBAA6B;CAC3C,MAAM,GAAG,WAAA,GAAA,MAAA,YAAqB,SAAS,
|
|
1
|
+
{"version":3,"file":"use-force-update.cjs","names":[],"sources":["../../src/use-force-update/use-force-update.ts"],"sourcesContent":["import { useReducer } from 'react';\n\nconst reducer = (value: number) => (value + 1) % 1000000;\n\nexport function useForceUpdate(): () => void {\n const [, update] = useReducer(reducer, 0);\n return update;\n}\n"],"mappings":";;;AAEA,MAAM,WAAW,WAAmB,QAAQ,KAAK;AAEjD,SAAgB,iBAA6B;CAC3C,MAAM,GAAG,WAAA,GAAA,MAAA,YAAqB,SAAS,CAAC;CACxC,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-fullscreen.cjs","names":[],"sources":["../../src/use-fullscreen/use-fullscreen.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nfunction getFullscreenElement(): HTMLElement | null {\n const _document = window.document as any;\n\n const fullscreenElement =\n _document.fullscreenElement ||\n _document.webkitFullscreenElement ||\n _document.mozFullScreenElement ||\n _document.msFullscreenElement;\n\n return fullscreenElement;\n}\n\nfunction exitFullscreen() {\n const _document = window.document as any;\n\n if (typeof _document.exitFullscreen === 'function') {\n return _document.exitFullscreen();\n }\n if (typeof _document.msExitFullscreen === 'function') {\n return _document.msExitFullscreen();\n }\n if (typeof _document.webkitExitFullscreen === 'function') {\n return _document.webkitExitFullscreen();\n }\n if (typeof _document.mozCancelFullScreen === 'function') {\n return _document.mozCancelFullScreen();\n }\n\n return null;\n}\n\nfunction enterFullScreen(element: HTMLElement) {\n const _element = element as any;\n\n return (\n _element.requestFullscreen?.() ||\n _element.msRequestFullscreen?.() ||\n _element.webkitEnterFullscreen?.() ||\n _element.webkitRequestFullscreen?.() ||\n _element.mozRequestFullscreen?.()\n );\n}\n\nconst prefixes = ['', 'webkit', 'moz', 'ms'];\n\ninterface FullscreenEvents {\n onFullScreen: (event: Event) => void;\n onError: (event: Event) => void;\n}\n\nfunction addEvents(element: HTMLElement, events: FullscreenEvents) {\n const { onFullScreen, onError } = events;\n prefixes.forEach((prefix) => {\n element.addEventListener(`${prefix}fullscreenchange`, onFullScreen);\n element.addEventListener(`${prefix}fullscreenerror`, onError);\n });\n\n return () => removeEvents(element, events);\n}\n\nfunction removeEvents(element: HTMLElement, { onFullScreen, onError }: FullscreenEvents) {\n prefixes.forEach((prefix) => {\n element.removeEventListener(`${prefix}fullscreenchange`, onFullScreen);\n element.removeEventListener(`${prefix}fullscreenerror`, onError);\n });\n}\n\nexport interface UseFullscreenElementReturnValue<T extends HTMLElement = any> {\n ref: React.RefCallback<T | null>;\n toggle: () => Promise<void>;\n fullscreen: boolean;\n}\n\nexport function useFullscreenElement<\n T extends HTMLElement = any,\n>(): UseFullscreenElementReturnValue<T> {\n const [fullscreen, setFullscreen] = useState<boolean>(false);\n const refElement = useRef<T | null>(null);\n const prevNodeRef = useRef<T | null>(null);\n\n const handleFullscreenChange = useCallback(() => {\n setFullscreen(refElement.current === getFullscreenElement());\n }, []);\n\n const handleFullscreenError = useCallback(() => {\n setFullscreen(false);\n }, []);\n\n const toggle = useCallback(async () => {\n if (!getFullscreenElement() && refElement.current) {\n await enterFullScreen(refElement.current);\n } else {\n await exitFullscreen();\n }\n }, []);\n\n const refCallback: React.RefCallback<T | null> = useCallback((node) => {\n if (prevNodeRef.current && prevNodeRef.current !== node) {\n removeEvents(prevNodeRef.current, {\n onFullScreen: handleFullscreenChange,\n onError: handleFullscreenError,\n });\n }\n\n if (node) {\n addEvents(node, {\n onFullScreen: handleFullscreenChange,\n onError: handleFullscreenError,\n });\n }\n\n refElement.current = node;\n prevNodeRef.current = node;\n }, []);\n\n return { ref: refCallback, toggle, fullscreen };\n}\n\nexport interface UseFullscreenDocumentReturnValue {\n toggle: () => Promise<void>;\n fullscreen: boolean;\n}\n\nexport function useFullscreenDocument(): UseFullscreenDocumentReturnValue {\n const [fullscreen, setFullscreen] = useState<boolean>(false);\n\n const handleFullscreenChange = useCallback(() => {\n setFullscreen(getFullscreenElement() === window.document.documentElement);\n }, []);\n\n const handleFullscreenError = useCallback(() => {\n setFullscreen(false);\n }, []);\n\n const toggle = useCallback(async () => {\n if (!getFullscreenElement()) {\n await enterFullScreen(window.document.documentElement);\n } else {\n await exitFullscreen();\n }\n }, []);\n\n useEffect(() => {\n return addEvents(window.document.documentElement, {\n onFullScreen: handleFullscreenChange,\n onError: handleFullscreenError,\n });\n }, []);\n\n return { toggle, fullscreen };\n}\n"],"mappings":";;;AAEA,SAAS,uBAA2C;CAClD,MAAM,YAAY,OAAO;
|
|
1
|
+
{"version":3,"file":"use-fullscreen.cjs","names":[],"sources":["../../src/use-fullscreen/use-fullscreen.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nfunction getFullscreenElement(): HTMLElement | null {\n const _document = window.document as any;\n\n const fullscreenElement =\n _document.fullscreenElement ||\n _document.webkitFullscreenElement ||\n _document.mozFullScreenElement ||\n _document.msFullscreenElement;\n\n return fullscreenElement;\n}\n\nfunction exitFullscreen() {\n const _document = window.document as any;\n\n if (typeof _document.exitFullscreen === 'function') {\n return _document.exitFullscreen();\n }\n if (typeof _document.msExitFullscreen === 'function') {\n return _document.msExitFullscreen();\n }\n if (typeof _document.webkitExitFullscreen === 'function') {\n return _document.webkitExitFullscreen();\n }\n if (typeof _document.mozCancelFullScreen === 'function') {\n return _document.mozCancelFullScreen();\n }\n\n return null;\n}\n\nfunction enterFullScreen(element: HTMLElement) {\n const _element = element as any;\n\n return (\n _element.requestFullscreen?.() ||\n _element.msRequestFullscreen?.() ||\n _element.webkitEnterFullscreen?.() ||\n _element.webkitRequestFullscreen?.() ||\n _element.mozRequestFullscreen?.()\n );\n}\n\nconst prefixes = ['', 'webkit', 'moz', 'ms'];\n\ninterface FullscreenEvents {\n onFullScreen: (event: Event) => void;\n onError: (event: Event) => void;\n}\n\nfunction addEvents(element: HTMLElement, events: FullscreenEvents) {\n const { onFullScreen, onError } = events;\n prefixes.forEach((prefix) => {\n element.addEventListener(`${prefix}fullscreenchange`, onFullScreen);\n element.addEventListener(`${prefix}fullscreenerror`, onError);\n });\n\n return () => removeEvents(element, events);\n}\n\nfunction removeEvents(element: HTMLElement, { onFullScreen, onError }: FullscreenEvents) {\n prefixes.forEach((prefix) => {\n element.removeEventListener(`${prefix}fullscreenchange`, onFullScreen);\n element.removeEventListener(`${prefix}fullscreenerror`, onError);\n });\n}\n\nexport interface UseFullscreenElementReturnValue<T extends HTMLElement = any> {\n ref: React.RefCallback<T | null>;\n toggle: () => Promise<void>;\n fullscreen: boolean;\n}\n\nexport function useFullscreenElement<\n T extends HTMLElement = any,\n>(): UseFullscreenElementReturnValue<T> {\n const [fullscreen, setFullscreen] = useState<boolean>(false);\n const refElement = useRef<T | null>(null);\n const prevNodeRef = useRef<T | null>(null);\n\n const handleFullscreenChange = useCallback(() => {\n setFullscreen(refElement.current === getFullscreenElement());\n }, []);\n\n const handleFullscreenError = useCallback(() => {\n setFullscreen(false);\n }, []);\n\n const toggle = useCallback(async () => {\n if (!getFullscreenElement() && refElement.current) {\n await enterFullScreen(refElement.current);\n } else {\n await exitFullscreen();\n }\n }, []);\n\n const refCallback: React.RefCallback<T | null> = useCallback((node) => {\n if (prevNodeRef.current && prevNodeRef.current !== node) {\n removeEvents(prevNodeRef.current, {\n onFullScreen: handleFullscreenChange,\n onError: handleFullscreenError,\n });\n }\n\n if (node) {\n addEvents(node, {\n onFullScreen: handleFullscreenChange,\n onError: handleFullscreenError,\n });\n }\n\n refElement.current = node;\n prevNodeRef.current = node;\n }, []);\n\n return { ref: refCallback, toggle, fullscreen };\n}\n\nexport interface UseFullscreenDocumentReturnValue {\n toggle: () => Promise<void>;\n fullscreen: boolean;\n}\n\nexport function useFullscreenDocument(): UseFullscreenDocumentReturnValue {\n const [fullscreen, setFullscreen] = useState<boolean>(false);\n\n const handleFullscreenChange = useCallback(() => {\n setFullscreen(getFullscreenElement() === window.document.documentElement);\n }, []);\n\n const handleFullscreenError = useCallback(() => {\n setFullscreen(false);\n }, []);\n\n const toggle = useCallback(async () => {\n if (!getFullscreenElement()) {\n await enterFullScreen(window.document.documentElement);\n } else {\n await exitFullscreen();\n }\n }, []);\n\n useEffect(() => {\n return addEvents(window.document.documentElement, {\n onFullScreen: handleFullscreenChange,\n onError: handleFullscreenError,\n });\n }, []);\n\n return { toggle, fullscreen };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hash.cjs","names":[],"sources":["../../src/use-hash/use-hash.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useWindowEvent } from '../use-window-event/use-window-event';\n\nexport interface UseHashInput {\n getInitialValueInEffect?: boolean;\n}\n\nexport type UseHashReturnValue = [string, (value: string) => void];\n\nexport function useHash({ getInitialValueInEffect = true }: UseHashInput = {}): UseHashReturnValue {\n const [hash, setHash] = useState<string>(\n getInitialValueInEffect ? '' : window.location.hash || ''\n );\n\n const setHashHandler = (value: string) => {\n const valueWithHash = value.startsWith('#') ? value : `#${value}`;\n window.location.hash = valueWithHash;\n setHash(valueWithHash);\n };\n\n useWindowEvent('hashchange', () => {\n const newHash = window.location.hash;\n if (hash !== newHash) {\n setHash(newHash);\n }\n });\n\n useEffect(() => {\n if (getInitialValueInEffect) {\n setHash(window.location.hash);\n }\n }, []);\n\n return [hash, setHashHandler];\n}\n\nexport namespace useHash {\n export type Options = UseHashInput;\n export type ReturnValue = UseHashReturnValue;\n}\n"],"mappings":";;;;AASA,SAAgB,QAAQ,EAAE,0BAA0B,SAAuB,
|
|
1
|
+
{"version":3,"file":"use-hash.cjs","names":[],"sources":["../../src/use-hash/use-hash.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useWindowEvent } from '../use-window-event/use-window-event';\n\nexport interface UseHashInput {\n getInitialValueInEffect?: boolean;\n}\n\nexport type UseHashReturnValue = [string, (value: string) => void];\n\nexport function useHash({ getInitialValueInEffect = true }: UseHashInput = {}): UseHashReturnValue {\n const [hash, setHash] = useState<string>(\n getInitialValueInEffect ? '' : window.location.hash || ''\n );\n\n const setHashHandler = (value: string) => {\n const valueWithHash = value.startsWith('#') ? value : `#${value}`;\n window.location.hash = valueWithHash;\n setHash(valueWithHash);\n };\n\n useWindowEvent('hashchange', () => {\n const newHash = window.location.hash;\n if (hash !== newHash) {\n setHash(newHash);\n }\n });\n\n useEffect(() => {\n if (getInitialValueInEffect) {\n setHash(window.location.hash);\n }\n }, []);\n\n return [hash, setHashHandler];\n}\n\nexport namespace useHash {\n export type Options = UseHashInput;\n export type ReturnValue = UseHashReturnValue;\n}\n"],"mappings":";;;;AASA,SAAgB,QAAQ,EAAE,0BAA0B,SAAuB,CAAC,GAAuB;CACjG,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,UACX,0BAA0B,KAAK,OAAO,SAAS,QAAQ,EACzD;CAEA,MAAM,kBAAkB,UAAkB;EACxC,MAAM,gBAAgB,MAAM,WAAW,GAAG,IAAI,QAAQ,IAAI;EAC1D,OAAO,SAAS,OAAO;EACvB,QAAQ,aAAa;CACvB;CAEA,yBAAA,eAAe,oBAAoB;EACjC,MAAM,UAAU,OAAO,SAAS;EAChC,IAAI,SAAS,SACX,QAAQ,OAAO;CAEnB,CAAC;CAED,CAAA,GAAA,MAAA,iBAAgB;EACd,IAAI,yBACF,QAAQ,OAAO,SAAS,IAAI;CAEhC,GAAG,CAAC,CAAC;CAEL,OAAO,CAAC,MAAM,cAAc;AAC9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-headroom.cjs","names":["useScrollDirection","useWindowScroll"],"sources":["../../src/use-headroom/use-headroom.ts"],"sourcesContent":["import { useEffectEvent, useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\nimport { useScrollDirection } from '../use-scroll-direction/use-scroll-direction';\nimport { useWindowScroll } from '../use-window-scroll/use-window-scroll';\n\nexport { useScrollDirection } from '../use-scroll-direction/use-scroll-direction';\n\nexport const isFixed = (current: number, fixedAt: number) => current <= fixedAt;\nexport const isPinned = (current: number, previous: number) => current <= previous;\nexport const isReleased = (current: number, previous: number, fixedAt: number) =>\n !isPinned(current, previous) && !isFixed(current, fixedAt);\n\nexport const isPinnedOrReleased = (\n current: number,\n fixedAt: number,\n isCurrentlyPinnedRef: React.RefObject<boolean>,\n isScrollingUp: boolean,\n onPin?: () => void,\n onRelease?: () => void\n) => {\n const isInFixedPosition = isFixed(current, fixedAt);\n if (isInFixedPosition && !isCurrentlyPinnedRef.current) {\n isCurrentlyPinnedRef.current = true;\n onPin?.();\n } else if (!isInFixedPosition && isScrollingUp && !isCurrentlyPinnedRef.current) {\n isCurrentlyPinnedRef.current = true;\n onPin?.();\n } else if (!isInFixedPosition && !isScrollingUp && isCurrentlyPinnedRef.current) {\n isCurrentlyPinnedRef.current = false;\n onRelease?.();\n }\n};\n\nexport interface UseHeadroomInput {\n /** Number in px at which element should be fixed */\n fixedAt?: number;\n\n /** Number of px to scroll to fully reveal or hide the element, 100 by default */\n scrollDistance?: number;\n\n /** Called when element is pinned */\n onPin?: () => void;\n\n /** Called when element is at fixed position */\n onFix?: () => void;\n\n /** Called when element is unpinned */\n onRelease?: () => void;\n}\n\nexport interface UseHeadroomReturnValue {\n /** True when the element is at least partially visible */\n pinned: boolean;\n\n /** Reveal progress: 0 = fully hidden, 1 = fully visible */\n scrollProgress: number;\n}\n\nexport function useHeadroom({\n fixedAt = 0,\n scrollDistance = 100,\n onPin,\n onFix,\n onRelease,\n}: UseHeadroomInput = {}): UseHeadroomReturnValue {\n const isCurrentlyPinnedRef = useRef(false);\n const scrollDirection = useScrollDirection();\n const isScrollingUp = scrollDirection === 'up';\n const [{ y: scrollPosition }] = useWindowScroll();\n\n const onPinEvent = useEffectEvent(() => onPin?.());\n const onReleaseEvent = useEffectEvent(() => onRelease?.());\n const onFixEvent = useEffectEvent(() => onFix?.());\n\n useIsomorphicEffect(() => {\n isPinnedOrReleased(\n scrollPosition,\n fixedAt,\n isCurrentlyPinnedRef,\n isScrollingUp,\n onPinEvent,\n onReleaseEvent\n );\n }, [scrollPosition, fixedAt, isScrollingUp]);\n\n const wasFixedRef = useRef(false);\n\n useIsomorphicEffect(() => {\n const currentlyInFixedZone = isFixed(scrollPosition, fixedAt);\n if (currentlyInFixedZone && !wasFixedRef.current) {\n onFixEvent();\n }\n wasFixedRef.current = currentlyInFixedZone;\n }, [scrollPosition, fixedAt]);\n\n // Refs for scroll-progress tracking. Mutated during render (safe for refs).\n const currentlyFixed = isFixed(scrollPosition, fixedAt);\n const prevIsFixedRef = useRef(currentlyFixed);\n const directionChangeScrollYRef = useRef(scrollPosition);\n const progressAtDirectionChangeRef = useRef(currentlyFixed ? 1 : 0);\n const prevIsScrollingUpRef = useRef(isScrollingUp);\n\n // Detect fixed-zone transitions first. When leaving the fixed zone the baseline\n // is anchored at fixedAt (not the current scroll position) so the delta is measured\n // from where the element was last fully visible, regardless of how scroll position\n // was initialised on the first render.\n if (prevIsFixedRef.current !== currentlyFixed) {\n prevIsFixedRef.current = currentlyFixed;\n\n if (!currentlyFixed) {\n directionChangeScrollYRef.current = fixedAt;\n progressAtDirectionChangeRef.current = 1;\n } else {\n directionChangeScrollYRef.current = scrollPosition;\n progressAtDirectionChangeRef.current = 1;\n }\n\n prevIsScrollingUpRef.current = isScrollingUp;\n }\n\n // When scroll direction changes outside the fixed zone, save the current progress\n // so the next direction accumulates from that point (handles partial reveals).\n if (!currentlyFixed && prevIsScrollingUpRef.current !== isScrollingUp) {\n const transitionDelta = Math.abs(scrollPosition - directionChangeScrollYRef.current);\n const transitionProgress = prevIsScrollingUpRef.current\n ? Math.min(progressAtDirectionChangeRef.current + transitionDelta / scrollDistance, 1)\n : Math.max(progressAtDirectionChangeRef.current - transitionDelta / scrollDistance, 0);\n\n prevIsScrollingUpRef.current = isScrollingUp;\n directionChangeScrollYRef.current = scrollPosition;\n progressAtDirectionChangeRef.current = transitionProgress;\n }\n\n let scrollProgress: number;\n\n if (currentlyFixed) {\n scrollProgress = 1;\n } else {\n const scrollDelta = Math.abs(scrollPosition - directionChangeScrollYRef.current);\n\n if (isScrollingUp) {\n scrollProgress = Math.min(\n progressAtDirectionChangeRef.current + scrollDelta / scrollDistance,\n 1\n );\n } else {\n scrollProgress = Math.max(\n progressAtDirectionChangeRef.current - scrollDelta / scrollDistance,\n 0\n );\n }\n }\n\n return { pinned: scrollProgress > 0, scrollProgress };\n}\n\nexport namespace useHeadroom {\n export type Input = UseHeadroomInput;\n export type ReturnValue = UseHeadroomReturnValue;\n}\n"],"mappings":";;;;;;AAOA,MAAa,WAAW,SAAiB,YAAoB,WAAW;AAKxE,MAAa,sBACX,SACA,SACA,sBACA,eACA,OACA,cACG;CACH,MAAM,oBAAoB,QAAQ,SAAS,
|
|
1
|
+
{"version":3,"file":"use-headroom.cjs","names":["useScrollDirection","useWindowScroll"],"sources":["../../src/use-headroom/use-headroom.ts"],"sourcesContent":["import { useEffectEvent, useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\nimport { useScrollDirection } from '../use-scroll-direction/use-scroll-direction';\nimport { useWindowScroll } from '../use-window-scroll/use-window-scroll';\n\nexport { useScrollDirection } from '../use-scroll-direction/use-scroll-direction';\n\nexport const isFixed = (current: number, fixedAt: number) => current <= fixedAt;\nexport const isPinned = (current: number, previous: number) => current <= previous;\nexport const isReleased = (current: number, previous: number, fixedAt: number) =>\n !isPinned(current, previous) && !isFixed(current, fixedAt);\n\nexport const isPinnedOrReleased = (\n current: number,\n fixedAt: number,\n isCurrentlyPinnedRef: React.RefObject<boolean>,\n isScrollingUp: boolean,\n onPin?: () => void,\n onRelease?: () => void\n) => {\n const isInFixedPosition = isFixed(current, fixedAt);\n if (isInFixedPosition && !isCurrentlyPinnedRef.current) {\n isCurrentlyPinnedRef.current = true;\n onPin?.();\n } else if (!isInFixedPosition && isScrollingUp && !isCurrentlyPinnedRef.current) {\n isCurrentlyPinnedRef.current = true;\n onPin?.();\n } else if (!isInFixedPosition && !isScrollingUp && isCurrentlyPinnedRef.current) {\n isCurrentlyPinnedRef.current = false;\n onRelease?.();\n }\n};\n\nexport interface UseHeadroomInput {\n /** Number in px at which element should be fixed */\n fixedAt?: number;\n\n /** Number of px to scroll to fully reveal or hide the element, 100 by default */\n scrollDistance?: number;\n\n /** Called when element is pinned */\n onPin?: () => void;\n\n /** Called when element is at fixed position */\n onFix?: () => void;\n\n /** Called when element is unpinned */\n onRelease?: () => void;\n}\n\nexport interface UseHeadroomReturnValue {\n /** True when the element is at least partially visible */\n pinned: boolean;\n\n /** Reveal progress: 0 = fully hidden, 1 = fully visible */\n scrollProgress: number;\n}\n\nexport function useHeadroom({\n fixedAt = 0,\n scrollDistance = 100,\n onPin,\n onFix,\n onRelease,\n}: UseHeadroomInput = {}): UseHeadroomReturnValue {\n const isCurrentlyPinnedRef = useRef(false);\n const scrollDirection = useScrollDirection();\n const isScrollingUp = scrollDirection === 'up';\n const [{ y: scrollPosition }] = useWindowScroll();\n\n const onPinEvent = useEffectEvent(() => onPin?.());\n const onReleaseEvent = useEffectEvent(() => onRelease?.());\n const onFixEvent = useEffectEvent(() => onFix?.());\n\n useIsomorphicEffect(() => {\n isPinnedOrReleased(\n scrollPosition,\n fixedAt,\n isCurrentlyPinnedRef,\n isScrollingUp,\n onPinEvent,\n onReleaseEvent\n );\n }, [scrollPosition, fixedAt, isScrollingUp]);\n\n const wasFixedRef = useRef(false);\n\n useIsomorphicEffect(() => {\n const currentlyInFixedZone = isFixed(scrollPosition, fixedAt);\n if (currentlyInFixedZone && !wasFixedRef.current) {\n onFixEvent();\n }\n wasFixedRef.current = currentlyInFixedZone;\n }, [scrollPosition, fixedAt]);\n\n // Refs for scroll-progress tracking. Mutated during render (safe for refs).\n const currentlyFixed = isFixed(scrollPosition, fixedAt);\n const prevIsFixedRef = useRef(currentlyFixed);\n const directionChangeScrollYRef = useRef(scrollPosition);\n const progressAtDirectionChangeRef = useRef(currentlyFixed ? 1 : 0);\n const prevIsScrollingUpRef = useRef(isScrollingUp);\n\n // Detect fixed-zone transitions first. When leaving the fixed zone the baseline\n // is anchored at fixedAt (not the current scroll position) so the delta is measured\n // from where the element was last fully visible, regardless of how scroll position\n // was initialised on the first render.\n if (prevIsFixedRef.current !== currentlyFixed) {\n prevIsFixedRef.current = currentlyFixed;\n\n if (!currentlyFixed) {\n directionChangeScrollYRef.current = fixedAt;\n progressAtDirectionChangeRef.current = 1;\n } else {\n directionChangeScrollYRef.current = scrollPosition;\n progressAtDirectionChangeRef.current = 1;\n }\n\n prevIsScrollingUpRef.current = isScrollingUp;\n }\n\n // When scroll direction changes outside the fixed zone, save the current progress\n // so the next direction accumulates from that point (handles partial reveals).\n if (!currentlyFixed && prevIsScrollingUpRef.current !== isScrollingUp) {\n const transitionDelta = Math.abs(scrollPosition - directionChangeScrollYRef.current);\n const transitionProgress = prevIsScrollingUpRef.current\n ? Math.min(progressAtDirectionChangeRef.current + transitionDelta / scrollDistance, 1)\n : Math.max(progressAtDirectionChangeRef.current - transitionDelta / scrollDistance, 0);\n\n prevIsScrollingUpRef.current = isScrollingUp;\n directionChangeScrollYRef.current = scrollPosition;\n progressAtDirectionChangeRef.current = transitionProgress;\n }\n\n let scrollProgress: number;\n\n if (currentlyFixed) {\n scrollProgress = 1;\n } else {\n const scrollDelta = Math.abs(scrollPosition - directionChangeScrollYRef.current);\n\n if (isScrollingUp) {\n scrollProgress = Math.min(\n progressAtDirectionChangeRef.current + scrollDelta / scrollDistance,\n 1\n );\n } else {\n scrollProgress = Math.max(\n progressAtDirectionChangeRef.current - scrollDelta / scrollDistance,\n 0\n );\n }\n }\n\n return { pinned: scrollProgress > 0, scrollProgress };\n}\n\nexport namespace useHeadroom {\n export type Input = UseHeadroomInput;\n export type ReturnValue = UseHeadroomReturnValue;\n}\n"],"mappings":";;;;;;AAOA,MAAa,WAAW,SAAiB,YAAoB,WAAW;AAKxE,MAAa,sBACX,SACA,SACA,sBACA,eACA,OACA,cACG;CACH,MAAM,oBAAoB,QAAQ,SAAS,OAAO;CAClD,IAAI,qBAAqB,CAAC,qBAAqB,SAAS;EACtD,qBAAqB,UAAU;EAC/B,QAAQ;CACV,OAAO,IAAI,CAAC,qBAAqB,iBAAiB,CAAC,qBAAqB,SAAS;EAC/E,qBAAqB,UAAU;EAC/B,QAAQ;CACV,OAAO,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,qBAAqB,SAAS;EAC/E,qBAAqB,UAAU;EAC/B,YAAY;CACd;AACF;AA2BA,SAAgB,YAAY,EAC1B,UAAU,GACV,iBAAiB,KACjB,OACA,OACA,cACoB,CAAC,GAA2B;CAChD,MAAM,wBAAA,GAAA,MAAA,QAA8B,KAAK;CAEzC,MAAM,gBADkBA,6BAAAA,mBACY,MAAM;CAC1C,MAAM,CAAC,EAAE,GAAG,oBAAoBC,0BAAAA,gBAAgB;CAEhD,MAAM,cAAA,GAAA,MAAA,sBAAkC,QAAQ,CAAC;CACjD,MAAM,kBAAA,GAAA,MAAA,sBAAsC,YAAY,CAAC;CACzD,MAAM,cAAA,GAAA,MAAA,sBAAkC,QAAQ,CAAC;CAEjD,8BAAA,0BAA0B;EACxB,mBACE,gBACA,SACA,sBACA,eACA,YACA,cACF;CACF,GAAG;EAAC;EAAgB;EAAS;CAAa,CAAC;CAE3C,MAAM,eAAA,GAAA,MAAA,QAAqB,KAAK;CAEhC,8BAAA,0BAA0B;EACxB,MAAM,uBAAuB,QAAQ,gBAAgB,OAAO;EAC5D,IAAI,wBAAwB,CAAC,YAAY,SACvC,WAAW;EAEb,YAAY,UAAU;CACxB,GAAG,CAAC,gBAAgB,OAAO,CAAC;CAG5B,MAAM,iBAAiB,QAAQ,gBAAgB,OAAO;CACtD,MAAM,kBAAA,GAAA,MAAA,QAAwB,cAAc;CAC5C,MAAM,6BAAA,GAAA,MAAA,QAAmC,cAAc;CACvD,MAAM,gCAAA,GAAA,MAAA,QAAsC,iBAAiB,IAAI,CAAC;CAClE,MAAM,wBAAA,GAAA,MAAA,QAA8B,aAAa;CAMjD,IAAI,eAAe,YAAY,gBAAgB;EAC7C,eAAe,UAAU;EAEzB,IAAI,CAAC,gBAAgB;GACnB,0BAA0B,UAAU;GACpC,6BAA6B,UAAU;EACzC,OAAO;GACL,0BAA0B,UAAU;GACpC,6BAA6B,UAAU;EACzC;EAEA,qBAAqB,UAAU;CACjC;CAIA,IAAI,CAAC,kBAAkB,qBAAqB,YAAY,eAAe;EACrE,MAAM,kBAAkB,KAAK,IAAI,iBAAiB,0BAA0B,OAAO;EACnF,MAAM,qBAAqB,qBAAqB,UAC5C,KAAK,IAAI,6BAA6B,UAAU,kBAAkB,gBAAgB,CAAC,IACnF,KAAK,IAAI,6BAA6B,UAAU,kBAAkB,gBAAgB,CAAC;EAEvF,qBAAqB,UAAU;EAC/B,0BAA0B,UAAU;EACpC,6BAA6B,UAAU;CACzC;CAEA,IAAI;CAEJ,IAAI,gBACF,iBAAiB;MACZ;EACL,MAAM,cAAc,KAAK,IAAI,iBAAiB,0BAA0B,OAAO;EAE/E,IAAI,eACF,iBAAiB,KAAK,IACpB,6BAA6B,UAAU,cAAc,gBACrD,CACF;OAEA,iBAAiB,KAAK,IACpB,6BAA6B,UAAU,cAAc,gBACrD,CACF;CAEJ;CAEA,OAAO;EAAE,QAAQ,iBAAiB;EAAG;CAAe;AACtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-hotkey.cjs","names":[],"sources":["../../src/use-hotkeys/parse-hotkey.ts"],"sourcesContent":["export interface KeyboardModifiers {\n alt: boolean;\n ctrl: boolean;\n meta: boolean;\n mod: boolean;\n shift: boolean;\n}\n\nexport interface Hotkey extends KeyboardModifiers {\n key?: string;\n}\n\ntype CheckHotkeyMatch = (event: KeyboardEvent) => boolean;\n\nconst keyNameMap: Record<string, string> = {\n ' ': 'space',\n ArrowLeft: 'arrowleft',\n ArrowRight: 'arrowright',\n ArrowUp: 'arrowup',\n ArrowDown: 'arrowdown',\n Escape: 'escape',\n Esc: 'escape',\n esc: 'escape',\n Enter: 'enter',\n Tab: 'tab',\n Backspace: 'backspace',\n Delete: 'delete',\n Insert: 'insert',\n Home: 'home',\n End: 'end',\n PageUp: 'pageup',\n PageDown: 'pagedown',\n '+': 'plus',\n '-': 'minus',\n '*': 'asterisk',\n '/': 'slash',\n};\n\nfunction normalizeKey(key: string): string {\n const lowerKey = key.replace('Key', '').toLowerCase();\n return keyNameMap[key] || lowerKey;\n}\n\nexport function parseHotkey(hotkey: string): Hotkey {\n const keys = hotkey\n .toLowerCase()\n .split('+')\n .map((part) => part.trim());\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n ctrl: keys.includes('ctrl'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n shift: keys.includes('shift'),\n };\n\n const reservedKeys = ['alt', 'ctrl', 'meta', 'shift', 'mod'];\n\n const freeKey = keys.find((key) => !reservedKeys.includes(key));\n\n return {\n ...modifiers,\n key: freeKey === '[plus]' ? '+' : freeKey,\n };\n}\n\nfunction isExactHotkey(hotkey: Hotkey, event: KeyboardEvent, usePhysicalKeys?: boolean): boolean {\n const { alt, ctrl, meta, mod, shift, key } = hotkey;\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey, code: pressedCode } = event;\n\n if (alt !== altKey) {\n return false;\n }\n\n if (mod) {\n if (!ctrlKey && !metaKey) {\n return false;\n }\n } else {\n if (ctrl !== ctrlKey) {\n return false;\n }\n if (meta !== metaKey) {\n return false;\n }\n }\n if (shift !== shiftKey) {\n return false;\n }\n\n if (\n key &&\n (usePhysicalKeys\n ? normalizeKey(pressedCode) === normalizeKey(key)\n : normalizeKey(pressedKey ?? pressedCode) === normalizeKey(key))\n ) {\n return true;\n }\n\n return false;\n}\n\nexport function getHotkeyMatcher(hotkey: string, usePhysicalKeys?: boolean): CheckHotkeyMatch {\n return (event) => isExactHotkey(parseHotkey(hotkey), event, usePhysicalKeys);\n}\n\nexport interface HotkeyItemOptions {\n preventDefault?: boolean;\n usePhysicalKeys?: boolean;\n}\n\ntype HotkeyItem = [string, (event: any) => void, HotkeyItemOptions?];\n\nexport function getHotkeyHandler(hotkeys: HotkeyItem[]) {\n return (event: React.KeyboardEvent<HTMLElement> | KeyboardEvent) => {\n const _event = 'nativeEvent' in event ? event.nativeEvent : event;\n hotkeys.forEach(\n ([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (getHotkeyMatcher(hotkey, options.usePhysicalKeys)(_event)) {\n if (options.preventDefault) {\n event.preventDefault();\n }\n\n handler(_event);\n }\n }\n );\n };\n}\n"],"mappings":";;AAcA,MAAM,aAAqC;CACzC,KAAK;CACL,WAAW;CACX,YAAY;CACZ,SAAS;CACT,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,OAAO;CACP,KAAK;CACL,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,KAAK;CACL,QAAQ;CACR,UAAU;CACV,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;
|
|
1
|
+
{"version":3,"file":"parse-hotkey.cjs","names":[],"sources":["../../src/use-hotkeys/parse-hotkey.ts"],"sourcesContent":["export interface KeyboardModifiers {\n alt: boolean;\n ctrl: boolean;\n meta: boolean;\n mod: boolean;\n shift: boolean;\n}\n\nexport interface Hotkey extends KeyboardModifiers {\n key?: string;\n}\n\ntype CheckHotkeyMatch = (event: KeyboardEvent) => boolean;\n\nconst keyNameMap: Record<string, string> = {\n ' ': 'space',\n ArrowLeft: 'arrowleft',\n ArrowRight: 'arrowright',\n ArrowUp: 'arrowup',\n ArrowDown: 'arrowdown',\n Escape: 'escape',\n Esc: 'escape',\n esc: 'escape',\n Enter: 'enter',\n Tab: 'tab',\n Backspace: 'backspace',\n Delete: 'delete',\n Insert: 'insert',\n Home: 'home',\n End: 'end',\n PageUp: 'pageup',\n PageDown: 'pagedown',\n '+': 'plus',\n '-': 'minus',\n '*': 'asterisk',\n '/': 'slash',\n};\n\nfunction normalizeKey(key: string): string {\n const lowerKey = key.replace('Key', '').toLowerCase();\n return keyNameMap[key] || lowerKey;\n}\n\nexport function parseHotkey(hotkey: string): Hotkey {\n const keys = hotkey\n .toLowerCase()\n .split('+')\n .map((part) => part.trim());\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n ctrl: keys.includes('ctrl'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n shift: keys.includes('shift'),\n };\n\n const reservedKeys = ['alt', 'ctrl', 'meta', 'shift', 'mod'];\n\n const freeKey = keys.find((key) => !reservedKeys.includes(key));\n\n return {\n ...modifiers,\n key: freeKey === '[plus]' ? '+' : freeKey,\n };\n}\n\nfunction isExactHotkey(hotkey: Hotkey, event: KeyboardEvent, usePhysicalKeys?: boolean): boolean {\n const { alt, ctrl, meta, mod, shift, key } = hotkey;\n const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey, code: pressedCode } = event;\n\n if (alt !== altKey) {\n return false;\n }\n\n if (mod) {\n if (!ctrlKey && !metaKey) {\n return false;\n }\n } else {\n if (ctrl !== ctrlKey) {\n return false;\n }\n if (meta !== metaKey) {\n return false;\n }\n }\n if (shift !== shiftKey) {\n return false;\n }\n\n if (\n key &&\n (usePhysicalKeys\n ? normalizeKey(pressedCode) === normalizeKey(key)\n : normalizeKey(pressedKey ?? pressedCode) === normalizeKey(key))\n ) {\n return true;\n }\n\n return false;\n}\n\nexport function getHotkeyMatcher(hotkey: string, usePhysicalKeys?: boolean): CheckHotkeyMatch {\n return (event) => isExactHotkey(parseHotkey(hotkey), event, usePhysicalKeys);\n}\n\nexport interface HotkeyItemOptions {\n preventDefault?: boolean;\n usePhysicalKeys?: boolean;\n}\n\ntype HotkeyItem = [string, (event: any) => void, HotkeyItemOptions?];\n\nexport function getHotkeyHandler(hotkeys: HotkeyItem[]) {\n return (event: React.KeyboardEvent<HTMLElement> | KeyboardEvent) => {\n const _event = 'nativeEvent' in event ? event.nativeEvent : event;\n hotkeys.forEach(\n ([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (getHotkeyMatcher(hotkey, options.usePhysicalKeys)(_event)) {\n if (options.preventDefault) {\n event.preventDefault();\n }\n\n handler(_event);\n }\n }\n );\n };\n}\n"],"mappings":";;AAcA,MAAM,aAAqC;CACzC,KAAK;CACL,WAAW;CACX,YAAY;CACZ,SAAS;CACT,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,OAAO;CACP,KAAK;CACL,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,KAAK;CACL,QAAQ;CACR,UAAU;CACV,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAS,aAAa,KAAqB;CACzC,MAAM,WAAW,IAAI,QAAQ,OAAO,EAAE,EAAE,YAAY;CACpD,OAAO,WAAW,QAAQ;AAC5B;AAEA,SAAgB,YAAY,QAAwB;CAClD,MAAM,OAAO,OACV,YAAY,EACZ,MAAM,GAAG,EACT,KAAK,SAAS,KAAK,KAAK,CAAC;CAE5B,MAAM,YAA+B;EACnC,KAAK,KAAK,SAAS,KAAK;EACxB,MAAM,KAAK,SAAS,MAAM;EAC1B,MAAM,KAAK,SAAS,MAAM;EAC1B,KAAK,KAAK,SAAS,KAAK;EACxB,OAAO,KAAK,SAAS,OAAO;CAC9B;CAEA,MAAM,eAAe;EAAC;EAAO;EAAQ;EAAQ;EAAS;CAAK;CAE3D,MAAM,UAAU,KAAK,MAAM,QAAQ,CAAC,aAAa,SAAS,GAAG,CAAC;CAE9D,OAAO;EACL,GAAG;EACH,KAAK,YAAY,WAAW,MAAM;CACpC;AACF;AAEA,SAAS,cAAc,QAAgB,OAAsB,iBAAoC;CAC/F,MAAM,EAAE,KAAK,MAAM,MAAM,KAAK,OAAO,QAAQ;CAC7C,MAAM,EAAE,QAAQ,SAAS,SAAS,UAAU,KAAK,YAAY,MAAM,gBAAgB;CAEnF,IAAI,QAAQ,QACV,OAAO;CAGT,IAAI;MACE,CAAC,WAAW,CAAC,SACf,OAAO;CAAA,OAEJ;EACL,IAAI,SAAS,SACX,OAAO;EAET,IAAI,SAAS,SACX,OAAO;CAEX;CACA,IAAI,UAAU,UACZ,OAAO;CAGT,IACE,QACC,kBACG,aAAa,WAAW,MAAM,aAAa,GAAG,IAC9C,aAAa,cAAc,WAAW,MAAM,aAAa,GAAG,IAEhE,OAAO;CAGT,OAAO;AACT;AAEA,SAAgB,iBAAiB,QAAgB,iBAA6C;CAC5F,QAAQ,UAAU,cAAc,YAAY,MAAM,GAAG,OAAO,eAAe;AAC7E;AASA,SAAgB,iBAAiB,SAAuB;CACtD,QAAQ,UAA4D;EAClE,MAAM,SAAS,iBAAiB,QAAQ,MAAM,cAAc;EAC5D,QAAQ,SACL,CAAC,QAAQ,SAAS,UAAU;GAAE,gBAAgB;GAAM,iBAAiB;EAAM,OAAO;GACjF,IAAI,iBAAiB,QAAQ,QAAQ,eAAe,EAAE,MAAM,GAAG;IAC7D,IAAI,QAAQ,gBACV,MAAM,eAAe;IAGvB,QAAQ,MAAM;GAChB;EACF,CACF;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hotkeys.cjs","names":["getHotkeyMatcher"],"sources":["../../src/use-hotkeys/use-hotkeys.ts"],"sourcesContent":["import { useEffect, useEffectEvent } from 'react';\nimport { getHotkeyHandler, getHotkeyMatcher, HotkeyItemOptions } from './parse-hotkey';\n\nexport type { HotkeyItemOptions };\nexport { getHotkeyHandler };\n\nexport type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?];\n\nfunction shouldFireEvent(\n event: KeyboardEvent,\n tagsToIgnore: string[],\n triggerOnContentEditable = false\n) {\n if (event.target instanceof HTMLElement) {\n if (triggerOnContentEditable) {\n return !tagsToIgnore.includes(event.target.tagName);\n }\n\n return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName);\n }\n\n return true;\n}\n\nexport function useHotkeys(\n hotkeys: HotkeyItem[],\n tagsToIgnore: string[] = ['INPUT', 'TEXTAREA', 'SELECT'],\n triggerOnContentEditable = false\n) {\n const handleKeydown = useEffectEvent((event: KeyboardEvent) => {\n hotkeys.forEach(\n ([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (\n getHotkeyMatcher(hotkey, options.usePhysicalKeys)(event) &&\n shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)\n ) {\n if (options.preventDefault) {\n event.preventDefault();\n }\n\n handler(event);\n }\n }\n );\n });\n\n useEffect(() => {\n document.documentElement.addEventListener('keydown', handleKeydown);\n return () => document.documentElement.removeEventListener('keydown', handleKeydown);\n }, []);\n}\n\nexport namespace useHotkeys {\n export type Hotkey = HotkeyItem;\n}\n"],"mappings":";;;;AAQA,SAAS,gBACP,OACA,cACA,2BAA2B,OAC3B;
|
|
1
|
+
{"version":3,"file":"use-hotkeys.cjs","names":["getHotkeyMatcher"],"sources":["../../src/use-hotkeys/use-hotkeys.ts"],"sourcesContent":["import { useEffect, useEffectEvent } from 'react';\nimport { getHotkeyHandler, getHotkeyMatcher, HotkeyItemOptions } from './parse-hotkey';\n\nexport type { HotkeyItemOptions };\nexport { getHotkeyHandler };\n\nexport type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?];\n\nfunction shouldFireEvent(\n event: KeyboardEvent,\n tagsToIgnore: string[],\n triggerOnContentEditable = false\n) {\n if (event.target instanceof HTMLElement) {\n if (triggerOnContentEditable) {\n return !tagsToIgnore.includes(event.target.tagName);\n }\n\n return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName);\n }\n\n return true;\n}\n\nexport function useHotkeys(\n hotkeys: HotkeyItem[],\n tagsToIgnore: string[] = ['INPUT', 'TEXTAREA', 'SELECT'],\n triggerOnContentEditable = false\n) {\n const handleKeydown = useEffectEvent((event: KeyboardEvent) => {\n hotkeys.forEach(\n ([hotkey, handler, options = { preventDefault: true, usePhysicalKeys: false }]) => {\n if (\n getHotkeyMatcher(hotkey, options.usePhysicalKeys)(event) &&\n shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)\n ) {\n if (options.preventDefault) {\n event.preventDefault();\n }\n\n handler(event);\n }\n }\n );\n });\n\n useEffect(() => {\n document.documentElement.addEventListener('keydown', handleKeydown);\n return () => document.documentElement.removeEventListener('keydown', handleKeydown);\n }, []);\n}\n\nexport namespace useHotkeys {\n export type Hotkey = HotkeyItem;\n}\n"],"mappings":";;;;AAQA,SAAS,gBACP,OACA,cACA,2BAA2B,OAC3B;CACA,IAAI,MAAM,kBAAkB,aAAa;EACvC,IAAI,0BACF,OAAO,CAAC,aAAa,SAAS,MAAM,OAAO,OAAO;EAGpD,OAAO,CAAC,MAAM,OAAO,qBAAqB,CAAC,aAAa,SAAS,MAAM,OAAO,OAAO;CACvF;CAEA,OAAO;AACT;AAEA,SAAgB,WACd,SACA,eAAyB;CAAC;CAAS;CAAY;AAAQ,GACvD,2BAA2B,OAC3B;CACA,MAAM,iBAAA,GAAA,MAAA,iBAAgC,UAAyB;EAC7D,QAAQ,SACL,CAAC,QAAQ,SAAS,UAAU;GAAE,gBAAgB;GAAM,iBAAiB;EAAM,OAAO;GACjF,IACEA,qBAAAA,iBAAiB,QAAQ,QAAQ,eAAe,EAAE,KAAK,KACvD,gBAAgB,OAAO,cAAc,wBAAwB,GAC7D;IACA,IAAI,QAAQ,gBACV,MAAM,eAAe;IAGvB,QAAQ,KAAK;GACf;EACF,CACF;CACF,CAAC;CAED,CAAA,GAAA,MAAA,iBAAgB;EACd,SAAS,gBAAgB,iBAAiB,WAAW,aAAa;EAClE,aAAa,SAAS,gBAAgB,oBAAoB,WAAW,aAAa;CACpF,GAAG,CAAC,CAAC;AACP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hover.cjs","names":[],"sources":["../../src/use-hover/use-hover.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\nexport interface UseHoverReturnValue<T extends HTMLElement = any> {\n hovered: boolean;\n ref: React.RefCallback<T | null>;\n}\n\nexport function useHover<T extends HTMLElement = any>(): UseHoverReturnValue<T> {\n const [hovered, setHovered] = useState(false);\n const previousNode = useRef<HTMLElement>(null);\n\n const handleMouseEnter = useCallback(() => {\n setHovered(true);\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n setHovered(false);\n }, []);\n\n const ref: React.RefCallback<T | null> = useCallback(\n (node) => {\n if (previousNode.current) {\n previousNode.current.removeEventListener('mouseenter', handleMouseEnter);\n previousNode.current.removeEventListener('mouseleave', handleMouseLeave);\n }\n\n if (node) {\n node.addEventListener('mouseenter', handleMouseEnter);\n node.addEventListener('mouseleave', handleMouseLeave);\n }\n\n previousNode.current = node;\n\n return () => {\n previousNode.current = null;\n setHovered(false);\n };\n },\n [handleMouseEnter, handleMouseLeave]\n );\n\n return { ref, hovered };\n}\n\nexport namespace useHover {\n export type ReturnValue<T extends HTMLElement> = UseHoverReturnValue<T>;\n}\n"],"mappings":";;;AAOA,SAAgB,WAAgE;CAC9E,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,UAAuB,
|
|
1
|
+
{"version":3,"file":"use-hover.cjs","names":[],"sources":["../../src/use-hover/use-hover.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\nexport interface UseHoverReturnValue<T extends HTMLElement = any> {\n hovered: boolean;\n ref: React.RefCallback<T | null>;\n}\n\nexport function useHover<T extends HTMLElement = any>(): UseHoverReturnValue<T> {\n const [hovered, setHovered] = useState(false);\n const previousNode = useRef<HTMLElement>(null);\n\n const handleMouseEnter = useCallback(() => {\n setHovered(true);\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n setHovered(false);\n }, []);\n\n const ref: React.RefCallback<T | null> = useCallback(\n (node) => {\n if (previousNode.current) {\n previousNode.current.removeEventListener('mouseenter', handleMouseEnter);\n previousNode.current.removeEventListener('mouseleave', handleMouseLeave);\n }\n\n if (node) {\n node.addEventListener('mouseenter', handleMouseEnter);\n node.addEventListener('mouseleave', handleMouseLeave);\n }\n\n previousNode.current = node;\n\n return () => {\n previousNode.current = null;\n setHovered(false);\n };\n },\n [handleMouseEnter, handleMouseLeave]\n );\n\n return { ref, hovered };\n}\n\nexport namespace useHover {\n export type ReturnValue<T extends HTMLElement> = UseHoverReturnValue<T>;\n}\n"],"mappings":";;;AAOA,SAAgB,WAAgE;CAC9E,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,UAAuB,KAAK;CAC5C,MAAM,gBAAA,GAAA,MAAA,QAAmC,IAAI;CAE7C,MAAM,oBAAA,GAAA,MAAA,mBAAqC;EACzC,WAAW,IAAI;CACjB,GAAG,CAAC,CAAC;CAEL,MAAM,oBAAA,GAAA,MAAA,mBAAqC;EACzC,WAAW,KAAK;CAClB,GAAG,CAAC,CAAC;CAwBL,OAAO;EAAE,MAAA,GAAA,MAAA,cArBN,SAAS;GACR,IAAI,aAAa,SAAS;IACxB,aAAa,QAAQ,oBAAoB,cAAc,gBAAgB;IACvE,aAAa,QAAQ,oBAAoB,cAAc,gBAAgB;GACzE;GAEA,IAAI,MAAM;IACR,KAAK,iBAAiB,cAAc,gBAAgB;IACpD,KAAK,iBAAiB,cAAc,gBAAgB;GACtD;GAEA,aAAa,UAAU;GAEvB,aAAa;IACX,aAAa,UAAU;IACvB,WAAW,KAAK;GAClB;EACF,GACA,CAAC,kBAAkB,gBAAgB,CAG1B;EAAG;CAAQ;AACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-id.cjs","names":["randomId"],"sources":["../../src/use-id/use-id.ts"],"sourcesContent":["import { useId as useReactId, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\nimport { randomId } from '../utils';\n\nexport function useId(staticId?: string) {\n const reactId = useReactId();\n const [uuid, setUuid] = useState(`mantine-${reactId.replace(/:/g, '')}`);\n\n useIsomorphicEffect(() => {\n setUuid(randomId());\n }, []);\n\n if (typeof staticId === 'string') {\n return staticId;\n }\n\n return uuid;\n}\n"],"mappings":";;;;;AAIA,SAAgB,MAAM,UAAmB;CAEvC,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,UAAoB,YAAA,GAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"use-id.cjs","names":["randomId"],"sources":["../../src/use-id/use-id.ts"],"sourcesContent":["import { useId as useReactId, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\nimport { randomId } from '../utils';\n\nexport function useId(staticId?: string) {\n const reactId = useReactId();\n const [uuid, setUuid] = useState(`mantine-${reactId.replace(/:/g, '')}`);\n\n useIsomorphicEffect(() => {\n setUuid(randomId());\n }, []);\n\n if (typeof staticId === 'string') {\n return staticId;\n }\n\n return uuid;\n}\n"],"mappings":";;;;;AAIA,SAAgB,MAAM,UAAmB;CAEvC,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,UAAoB,YAAA,GAAA,MAAA,OAAiB,EAAE,QAAQ,MAAM,EAAE,GAAG;CAEvE,8BAAA,0BAA0B;EACxB,QAAQA,kBAAAA,SAAS,CAAC;CACpB,GAAG,CAAC,CAAC;CAEL,IAAI,OAAO,aAAa,UACtB,OAAO;CAGT,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-idle.cjs","names":[],"sources":["../../src/use-idle/use-idle.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nexport interface UseIdleOptions {\n events?: (keyof DocumentEventMap)[];\n initialState?: boolean;\n}\n\nconst DEFAULT_OPTIONS: Required<UseIdleOptions> = {\n events: ['keydown', 'mousemove', 'touchmove', 'click', 'scroll', 'wheel'],\n initialState: true,\n};\n\nexport function useIdle(timeout: number, options?: UseIdleOptions) {\n const { events, initialState } = { ...DEFAULT_OPTIONS, ...options };\n const [idle, setIdle] = useState(initialState);\n const timer = useRef(-1);\n\n useEffect(() => {\n const handleEvents = () => {\n setIdle(false);\n\n if (timer.current) {\n window.clearTimeout(timer.current);\n }\n\n timer.current = window.setTimeout(() => {\n setIdle(true);\n }, timeout);\n };\n\n events.forEach((event) => document.addEventListener(event, handleEvents));\n\n // Start the timer immediately instead of waiting for the first event to happen\n timer.current = window.setTimeout(() => {\n setIdle(true);\n }, timeout);\n\n return () => {\n events.forEach((event) => document.removeEventListener(event, handleEvents));\n window.clearTimeout(timer.current);\n timer.current = -1;\n };\n }, [timeout]);\n\n return idle;\n}\n\nexport namespace useIdle {\n export type Options = UseIdleOptions;\n}\n"],"mappings":";;;AAOA,MAAM,kBAA4C;CAChD,QAAQ;EAAC;EAAW;EAAa;EAAa;EAAS;EAAU;
|
|
1
|
+
{"version":3,"file":"use-idle.cjs","names":[],"sources":["../../src/use-idle/use-idle.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nexport interface UseIdleOptions {\n events?: (keyof DocumentEventMap)[];\n initialState?: boolean;\n}\n\nconst DEFAULT_OPTIONS: Required<UseIdleOptions> = {\n events: ['keydown', 'mousemove', 'touchmove', 'click', 'scroll', 'wheel'],\n initialState: true,\n};\n\nexport function useIdle(timeout: number, options?: UseIdleOptions) {\n const { events, initialState } = { ...DEFAULT_OPTIONS, ...options };\n const [idle, setIdle] = useState(initialState);\n const timer = useRef(-1);\n\n useEffect(() => {\n const handleEvents = () => {\n setIdle(false);\n\n if (timer.current) {\n window.clearTimeout(timer.current);\n }\n\n timer.current = window.setTimeout(() => {\n setIdle(true);\n }, timeout);\n };\n\n events.forEach((event) => document.addEventListener(event, handleEvents));\n\n // Start the timer immediately instead of waiting for the first event to happen\n timer.current = window.setTimeout(() => {\n setIdle(true);\n }, timeout);\n\n return () => {\n events.forEach((event) => document.removeEventListener(event, handleEvents));\n window.clearTimeout(timer.current);\n timer.current = -1;\n };\n }, [timeout]);\n\n return idle;\n}\n\nexport namespace useIdle {\n export type Options = UseIdleOptions;\n}\n"],"mappings":";;;AAOA,MAAM,kBAA4C;CAChD,QAAQ;EAAC;EAAW;EAAa;EAAa;EAAS;EAAU;CAAO;CACxE,cAAc;AAChB;AAEA,SAAgB,QAAQ,SAAiB,SAA0B;CACjE,MAAM,EAAE,QAAQ,iBAAiB;EAAE,GAAG;EAAiB,GAAG;CAAQ;CAClE,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,UAAoB,YAAY;CAC7C,MAAM,SAAA,GAAA,MAAA,QAAe,EAAE;CAEvB,CAAA,GAAA,MAAA,iBAAgB;EACd,MAAM,qBAAqB;GACzB,QAAQ,KAAK;GAEb,IAAI,MAAM,SACR,OAAO,aAAa,MAAM,OAAO;GAGnC,MAAM,UAAU,OAAO,iBAAiB;IACtC,QAAQ,IAAI;GACd,GAAG,OAAO;EACZ;EAEA,OAAO,SAAS,UAAU,SAAS,iBAAiB,OAAO,YAAY,CAAC;EAGxE,MAAM,UAAU,OAAO,iBAAiB;GACtC,QAAQ,IAAI;EACd,GAAG,OAAO;EAEV,aAAa;GACX,OAAO,SAAS,UAAU,SAAS,oBAAoB,OAAO,YAAY,CAAC;GAC3E,OAAO,aAAa,MAAM,OAAO;GACjC,MAAM,UAAU;EAClB;CACF,GAAG,CAAC,OAAO,CAAC;CAEZ,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-in-viewport.cjs","names":[],"sources":["../../src/use-in-viewport/use-in-viewport.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\nexport interface UseInViewportReturnValue<T extends HTMLElement = any> {\n inViewport: boolean;\n ref: React.RefCallback<T | null>;\n}\n\nexport function useInViewport<T extends HTMLElement = any>(): UseInViewportReturnValue<T> {\n const observer = useRef<IntersectionObserver | null>(null);\n const [inViewport, setInViewport] = useState(false);\n\n const ref: React.RefCallback<T | null> = useCallback((node) => {\n if (typeof IntersectionObserver !== 'undefined') {\n observer.current?.disconnect();\n\n if (node) {\n observer.current = new IntersectionObserver((entries) => {\n const lastEntry = entries[entries.length - 1];\n setInViewport(lastEntry.isIntersecting);\n });\n observer.current.observe(node);\n } else {\n observer.current = null;\n setInViewport(false);\n }\n }\n }, []);\n\n return { ref, inViewport };\n}\n\nexport namespace useInViewport {\n export type ReturnValue<T extends HTMLElement> = UseInViewportReturnValue<T>;\n}\n"],"mappings":";;;AAOA,SAAgB,gBAA0E;CACxF,MAAM,YAAA,GAAA,MAAA,QAA+C,
|
|
1
|
+
{"version":3,"file":"use-in-viewport.cjs","names":[],"sources":["../../src/use-in-viewport/use-in-viewport.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\nexport interface UseInViewportReturnValue<T extends HTMLElement = any> {\n inViewport: boolean;\n ref: React.RefCallback<T | null>;\n}\n\nexport function useInViewport<T extends HTMLElement = any>(): UseInViewportReturnValue<T> {\n const observer = useRef<IntersectionObserver | null>(null);\n const [inViewport, setInViewport] = useState(false);\n\n const ref: React.RefCallback<T | null> = useCallback((node) => {\n if (typeof IntersectionObserver !== 'undefined') {\n observer.current?.disconnect();\n\n if (node) {\n observer.current = new IntersectionObserver((entries) => {\n const lastEntry = entries[entries.length - 1];\n setInViewport(lastEntry.isIntersecting);\n });\n observer.current.observe(node);\n } else {\n observer.current = null;\n setInViewport(false);\n }\n }\n }, []);\n\n return { ref, inViewport };\n}\n\nexport namespace useInViewport {\n export type ReturnValue<T extends HTMLElement> = UseInViewportReturnValue<T>;\n}\n"],"mappings":";;;AAOA,SAAgB,gBAA0E;CACxF,MAAM,YAAA,GAAA,MAAA,QAA+C,IAAI;CACzD,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,UAA0B,KAAK;CAmBlD,OAAO;EAAE,MAAA,GAAA,MAAA,cAjB6C,SAAS;GAC7D,IAAI,OAAO,yBAAyB,aAAa;IAC/C,SAAS,SAAS,WAAW;IAE7B,IAAI,MAAM;KACR,SAAS,UAAU,IAAI,sBAAsB,YAAY;MACvD,MAAM,YAAY,QAAQ,QAAQ,SAAS;MAC3C,cAAc,UAAU,cAAc;KACxC,CAAC;KACD,SAAS,QAAQ,QAAQ,IAAI;IAC/B,OAAO;KACL,SAAS,UAAU;KACnB,cAAc,KAAK;IACrB;GACF;EACF,GAAG,CAAC,CAEO;EAAG;CAAW;AAC3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-input-state.cjs","names":[],"sources":["../../src/use-input-state/use-input-state.ts"],"sourcesContent":["import { useState } from 'react';\n\nexport function getInputOnChange<T>(\n setValue: (value: null | undefined | T | ((current: T) => T)) => void\n) {\n return (val: null | undefined | T | React.ChangeEvent<any> | ((current: T) => T)) => {\n if (!val) {\n setValue(val as T);\n } else if (typeof val === 'function') {\n setValue(val);\n } else if (typeof val === 'object' && 'nativeEvent' in val) {\n const { currentTarget } = val;\n\n if (currentTarget.type === 'checkbox') {\n setValue((currentTarget as any).checked as any);\n } else {\n setValue(currentTarget.value as any);\n }\n } else {\n setValue(val);\n }\n };\n}\n\nexport type UseInputStateReturnValue<T> = [\n T,\n (value: null | undefined | T | React.ChangeEvent<any>) => void,\n];\n\nexport function useInputState<T>(initialState: T): UseInputStateReturnValue<T> {\n const [value, setValue] = useState<T>(initialState);\n return [value, getInputOnChange<T>(setValue as any)];\n}\n\nexport namespace useInputState {\n export type ReturnValue<T> = UseInputStateReturnValue<T>;\n}\n"],"mappings":";;;AAEA,SAAgB,iBACd,UACA;
|
|
1
|
+
{"version":3,"file":"use-input-state.cjs","names":[],"sources":["../../src/use-input-state/use-input-state.ts"],"sourcesContent":["import { useState } from 'react';\n\nexport function getInputOnChange<T>(\n setValue: (value: null | undefined | T | ((current: T) => T)) => void\n) {\n return (val: null | undefined | T | React.ChangeEvent<any> | ((current: T) => T)) => {\n if (!val) {\n setValue(val as T);\n } else if (typeof val === 'function') {\n setValue(val);\n } else if (typeof val === 'object' && 'nativeEvent' in val) {\n const { currentTarget } = val;\n\n if (currentTarget.type === 'checkbox') {\n setValue((currentTarget as any).checked as any);\n } else {\n setValue(currentTarget.value as any);\n }\n } else {\n setValue(val);\n }\n };\n}\n\nexport type UseInputStateReturnValue<T> = [\n T,\n (value: null | undefined | T | React.ChangeEvent<any>) => void,\n];\n\nexport function useInputState<T>(initialState: T): UseInputStateReturnValue<T> {\n const [value, setValue] = useState<T>(initialState);\n return [value, getInputOnChange<T>(setValue as any)];\n}\n\nexport namespace useInputState {\n export type ReturnValue<T> = UseInputStateReturnValue<T>;\n}\n"],"mappings":";;;AAEA,SAAgB,iBACd,UACA;CACA,QAAQ,QAA6E;EACnF,IAAI,CAAC,KACH,SAAS,GAAQ;OACZ,IAAI,OAAO,QAAQ,YACxB,SAAS,GAAG;OACP,IAAI,OAAO,QAAQ,YAAY,iBAAiB,KAAK;GAC1D,MAAM,EAAE,kBAAkB;GAE1B,IAAI,cAAc,SAAS,YACzB,SAAU,cAAsB,OAAc;QAE9C,SAAS,cAAc,KAAY;EAEvC,OACE,SAAS,GAAG;CAEhB;AACF;AAOA,SAAgB,cAAiB,cAA8C;CAC7E,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAwB,YAAY;CAClD,OAAO,CAAC,OAAO,iBAAoB,QAAe,CAAC;AACrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-intersection.cjs","names":[],"sources":["../../src/use-intersection/use-intersection.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\nexport interface UseIntersectionReturnValue<T> {\n ref: React.RefCallback<T | null>;\n entry: IntersectionObserverEntry | null;\n}\n\nexport function useIntersection<T extends HTMLElement = any>(\n options?: IntersectionObserverInit\n): UseIntersectionReturnValue<T> {\n const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null);\n\n const observer = useRef<IntersectionObserver | null>(null);\n\n const ref: React.RefCallback<T | null> = useCallback(\n (element) => {\n if (observer.current) {\n observer.current.disconnect();\n observer.current = null;\n }\n\n if (element === null) {\n setEntry(null);\n return;\n }\n\n observer.current = new IntersectionObserver(([_entry]) => {\n setEntry(_entry);\n }, options);\n\n observer.current.observe(element);\n },\n [options?.rootMargin, options?.root, options?.threshold]\n );\n\n return { ref, entry };\n}\n\nexport namespace useIntersection {\n export type ReturnValue<T> = UseIntersectionReturnValue<T>;\n}\n"],"mappings":";;;AAOA,SAAgB,gBACd,SAC+B;CAC/B,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAuD,
|
|
1
|
+
{"version":3,"file":"use-intersection.cjs","names":[],"sources":["../../src/use-intersection/use-intersection.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\nexport interface UseIntersectionReturnValue<T> {\n ref: React.RefCallback<T | null>;\n entry: IntersectionObserverEntry | null;\n}\n\nexport function useIntersection<T extends HTMLElement = any>(\n options?: IntersectionObserverInit\n): UseIntersectionReturnValue<T> {\n const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null);\n\n const observer = useRef<IntersectionObserver | null>(null);\n\n const ref: React.RefCallback<T | null> = useCallback(\n (element) => {\n if (observer.current) {\n observer.current.disconnect();\n observer.current = null;\n }\n\n if (element === null) {\n setEntry(null);\n return;\n }\n\n observer.current = new IntersectionObserver(([_entry]) => {\n setEntry(_entry);\n }, options);\n\n observer.current.observe(element);\n },\n [options?.rootMargin, options?.root, options?.threshold]\n );\n\n return { ref, entry };\n}\n\nexport namespace useIntersection {\n export type ReturnValue<T> = UseIntersectionReturnValue<T>;\n}\n"],"mappings":";;;AAOA,SAAgB,gBACd,SAC+B;CAC/B,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAuD,IAAI;CAEzE,MAAM,YAAA,GAAA,MAAA,QAA+C,IAAI;CAuBzD,OAAO;EAAE,MAAA,GAAA,MAAA,cApBN,YAAY;GACX,IAAI,SAAS,SAAS;IACpB,SAAS,QAAQ,WAAW;IAC5B,SAAS,UAAU;GACrB;GAEA,IAAI,YAAY,MAAM;IACpB,SAAS,IAAI;IACb;GACF;GAEA,SAAS,UAAU,IAAI,sBAAsB,CAAC,YAAY;IACxD,SAAS,MAAM;GACjB,GAAG,OAAO;GAEV,SAAS,QAAQ,QAAQ,OAAO;EAClC,GACA;GAAC,SAAS;GAAY,SAAS;GAAM,SAAS;EAAS,CAG9C;EAAG;CAAM;AACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-interval.cjs","names":[],"sources":["../../src/use-interval/use-interval.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseIntervalOptions {\n /** If set, the interval will start automatically when the component is mounted, `false` by default */\n autoInvoke?: boolean;\n}\n\nexport interface UseIntervalReturnValue {\n /** Starts the interval */\n start: () => void;\n\n /** Stops the interval */\n stop: () => void;\n\n /** Toggles the interval */\n toggle: () => void;\n\n /** Indicates if the interval is active */\n active: boolean;\n}\n\nexport function useInterval(\n fn: () => void,\n interval: number,\n { autoInvoke = false }: UseIntervalOptions = {}\n): UseIntervalReturnValue {\n const [active, setActive] = useState(false);\n const intervalRef = useRef<number | null>(null);\n const fnRef = useRef<() => void>(null);\n const intervalValueRef = useRef(interval);\n intervalValueRef.current = interval;\n\n const start = useCallback(() => {\n setActive((old) => {\n if (!old && !intervalRef.current) {\n intervalRef.current = window.setInterval(fnRef.current!, intervalValueRef.current);\n }\n return true;\n });\n }, []);\n\n const stop = useCallback(() => {\n setActive(false);\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current);\n }\n intervalRef.current = null;\n }, []);\n\n const toggle = useCallback(() => {\n setActive((current) => {\n if (current) {\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current);\n }\n intervalRef.current = null;\n return false;\n }\n if (!intervalRef.current) {\n intervalRef.current = window.setInterval(fnRef.current!, intervalValueRef.current);\n }\n return true;\n });\n }, []);\n\n useEffect(() => {\n fnRef.current = fn;\n active && start();\n return stop;\n }, [fn, active, interval]);\n\n useEffect(() => {\n if (autoInvoke) {\n start();\n }\n }, []);\n\n return { start, stop, toggle, active };\n}\n\nexport namespace useInterval {\n export type Options = UseIntervalOptions;\n export type ReturnValue = UseIntervalReturnValue;\n}\n"],"mappings":";;;AAqBA,SAAgB,YACd,IACA,UACA,EAAE,aAAa,UAA8B,
|
|
1
|
+
{"version":3,"file":"use-interval.cjs","names":[],"sources":["../../src/use-interval/use-interval.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseIntervalOptions {\n /** If set, the interval will start automatically when the component is mounted, `false` by default */\n autoInvoke?: boolean;\n}\n\nexport interface UseIntervalReturnValue {\n /** Starts the interval */\n start: () => void;\n\n /** Stops the interval */\n stop: () => void;\n\n /** Toggles the interval */\n toggle: () => void;\n\n /** Indicates if the interval is active */\n active: boolean;\n}\n\nexport function useInterval(\n fn: () => void,\n interval: number,\n { autoInvoke = false }: UseIntervalOptions = {}\n): UseIntervalReturnValue {\n const [active, setActive] = useState(false);\n const intervalRef = useRef<number | null>(null);\n const fnRef = useRef<() => void>(null);\n const intervalValueRef = useRef(interval);\n intervalValueRef.current = interval;\n\n const start = useCallback(() => {\n setActive((old) => {\n if (!old && !intervalRef.current) {\n intervalRef.current = window.setInterval(fnRef.current!, intervalValueRef.current);\n }\n return true;\n });\n }, []);\n\n const stop = useCallback(() => {\n setActive(false);\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current);\n }\n intervalRef.current = null;\n }, []);\n\n const toggle = useCallback(() => {\n setActive((current) => {\n if (current) {\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current);\n }\n intervalRef.current = null;\n return false;\n }\n if (!intervalRef.current) {\n intervalRef.current = window.setInterval(fnRef.current!, intervalValueRef.current);\n }\n return true;\n });\n }, []);\n\n useEffect(() => {\n fnRef.current = fn;\n active && start();\n return stop;\n }, [fn, active, interval]);\n\n useEffect(() => {\n if (autoInvoke) {\n start();\n }\n }, []);\n\n return { start, stop, toggle, active };\n}\n\nexport namespace useInterval {\n export type Options = UseIntervalOptions;\n export type ReturnValue = UseIntervalReturnValue;\n}\n"],"mappings":";;;AAqBA,SAAgB,YACd,IACA,UACA,EAAE,aAAa,UAA8B,CAAC,GACtB;CACxB,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,UAAsB,KAAK;CAC1C,MAAM,eAAA,GAAA,MAAA,QAAoC,IAAI;CAC9C,MAAM,SAAA,GAAA,MAAA,QAA2B,IAAI;CACrC,MAAM,oBAAA,GAAA,MAAA,QAA0B,QAAQ;CACxC,iBAAiB,UAAU;CAE3B,MAAM,SAAA,GAAA,MAAA,mBAA0B;EAC9B,WAAW,QAAQ;GACjB,IAAI,CAAC,OAAO,CAAC,YAAY,SACvB,YAAY,UAAU,OAAO,YAAY,MAAM,SAAU,iBAAiB,OAAO;GAEnF,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,QAAA,GAAA,MAAA,mBAAyB;EAC7B,UAAU,KAAK;EACf,IAAI,YAAY,SACd,OAAO,cAAc,YAAY,OAAO;EAE1C,YAAY,UAAU;CACxB,GAAG,CAAC,CAAC;CAEL,MAAM,UAAA,GAAA,MAAA,mBAA2B;EAC/B,WAAW,YAAY;GACrB,IAAI,SAAS;IACX,IAAI,YAAY,SACd,OAAO,cAAc,YAAY,OAAO;IAE1C,YAAY,UAAU;IACtB,OAAO;GACT;GACA,IAAI,CAAC,YAAY,SACf,YAAY,UAAU,OAAO,YAAY,MAAM,SAAU,iBAAiB,OAAO;GAEnF,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,iBAAgB;EACd,MAAM,UAAU;EAChB,UAAU,MAAM;EAChB,OAAO;CACT,GAAG;EAAC;EAAI;EAAQ;CAAQ,CAAC;CAEzB,CAAA,GAAA,MAAA,iBAAgB;EACd,IAAI,YACF,MAAM;CAEV,GAAG,CAAC,CAAC;CAEL,OAAO;EAAE;EAAO;EAAM;EAAQ;CAAO;AACvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-is-first-render.cjs","names":[],"sources":["../../src/use-is-first-render/use-is-first-render.ts"],"sourcesContent":["import { useRef } from 'react';\n\nexport function useIsFirstRender() {\n const renderRef = useRef(true);\n\n if (renderRef.current === true) {\n renderRef.current = false;\n return true;\n }\n\n return renderRef.current;\n}\n"],"mappings":";;;AAEA,SAAgB,mBAAmB;CACjC,MAAM,aAAA,GAAA,MAAA,QAAmB,
|
|
1
|
+
{"version":3,"file":"use-is-first-render.cjs","names":[],"sources":["../../src/use-is-first-render/use-is-first-render.ts"],"sourcesContent":["import { useRef } from 'react';\n\nexport function useIsFirstRender() {\n const renderRef = useRef(true);\n\n if (renderRef.current === true) {\n renderRef.current = false;\n return true;\n }\n\n return renderRef.current;\n}\n"],"mappings":";;;AAEA,SAAgB,mBAAmB;CACjC,MAAM,aAAA,GAAA,MAAA,QAAmB,IAAI;CAE7B,IAAI,UAAU,YAAY,MAAM;EAC9B,UAAU,UAAU;EACpB,OAAO;CACT;CAEA,OAAO,UAAU;AACnB"}
|