@koobiq/react-core 0.0.1-beta.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/hooks/index.d.ts +13 -0
  4. package/dist/hooks/useBoolean/index.d.ts +1 -0
  5. package/dist/hooks/useBoolean/useBoolean.d.ts +13 -0
  6. package/dist/hooks/useBoolean/useBoolean.js +11 -0
  7. package/dist/hooks/useDOMRef/index.d.ts +1 -0
  8. package/dist/hooks/useDOMRef/useDOMRef.d.ts +2 -0
  9. package/dist/hooks/useDOMRef/useDOMRef.js +9 -0
  10. package/dist/hooks/useElementSize/index.d.ts +1 -0
  11. package/dist/hooks/useElementSize/useElementSize.d.ts +5 -0
  12. package/dist/hooks/useElementSize/useElementSize.js +9 -0
  13. package/dist/hooks/useEventListener/index.d.ts +1 -0
  14. package/dist/hooks/useEventListener/useEventListener.d.ts +19 -0
  15. package/dist/hooks/useEventListener/useEventListener.js +32 -0
  16. package/dist/hooks/useInterval/index.d.ts +1 -0
  17. package/dist/hooks/useInterval/useInterval.d.ts +5 -0
  18. package/dist/hooks/useInterval/useInterval.js +18 -0
  19. package/dist/hooks/useIsFirstRender/index.d.ts +1 -0
  20. package/dist/hooks/useIsFirstRender/useIsFirstRender.d.ts +1 -0
  21. package/dist/hooks/useIsFirstRender/useIsFirstRender.js +13 -0
  22. package/dist/hooks/useIsomorphicEffect/index.d.ts +1 -0
  23. package/dist/hooks/useIsomorphicEffect/useIsomorphicEffect.d.ts +2 -0
  24. package/dist/hooks/useIsomorphicEffect/useIsomorphicEffect.js +6 -0
  25. package/dist/hooks/useMediaQuery/index.d.ts +1 -0
  26. package/dist/hooks/useMediaQuery/useMediaQuery.d.ts +15 -0
  27. package/dist/hooks/useMediaQuery/useMediaQuery.js +43 -0
  28. package/dist/hooks/useMultiRef/index.d.ts +1 -0
  29. package/dist/hooks/useMultiRef/useMultiRef.d.ts +4 -0
  30. package/dist/hooks/useMultiRef/useMultiRef.js +19 -0
  31. package/dist/hooks/useMutableRef/index.d.ts +1 -0
  32. package/dist/hooks/useMutableRef/useMutableRef.d.ts +1 -0
  33. package/dist/hooks/useMutableRef/useMutableRef.js +10 -0
  34. package/dist/hooks/usePrevious/index.d.ts +1 -0
  35. package/dist/hooks/usePrevious/usePrevious.d.ts +1 -0
  36. package/dist/hooks/usePrevious/usePrevious.js +11 -0
  37. package/dist/hooks/useResizeObserver/index.d.ts +1 -0
  38. package/dist/hooks/useResizeObserver/useResizeObserver.d.ts +3 -0
  39. package/dist/hooks/useResizeObserver/useResizeObserver.js +49 -0
  40. package/dist/hooks/useSsr/index.d.ts +1 -0
  41. package/dist/hooks/useSsr/useSsr.d.ts +7 -0
  42. package/dist/hooks/useSsr/useSsr.js +15 -0
  43. package/dist/index.d.ts +9 -0
  44. package/dist/index.js +55 -0
  45. package/dist/styles/clsx.d.ts +3 -0
  46. package/dist/styles/clsx.js +6 -0
  47. package/dist/styles/index.d.ts +1 -0
  48. package/dist/types/DataAttributeProps.d.ts +3 -0
  49. package/dist/types/DistributiveOmit.d.ts +1 -0
  50. package/dist/types/ExtendableComponentPropsWithRef.d.ts +3 -0
  51. package/dist/types/ExtendableProps.d.ts +2 -0
  52. package/dist/types/Merge.d.ts +3 -0
  53. package/dist/types/index.d.ts +5 -0
  54. package/dist/utils/capitalizeFirstLetter/capitalizeFirstLetter.d.ts +2 -0
  55. package/dist/utils/capitalizeFirstLetter/capitalizeFirstLetter.js +6 -0
  56. package/dist/utils/capitalizeFirstLetter/index.d.ts +1 -0
  57. package/dist/utils/index.d.ts +5 -0
  58. package/dist/utils/isBrowser.d.ts +1 -0
  59. package/dist/utils/isBrowser.js +6 -0
  60. package/dist/utils/polymorphicForwardRef.d.ts +13 -0
  61. package/dist/utils/polymorphicForwardRef.js +5 -0
  62. package/dist/utils/setRef.d.ts +4 -0
  63. package/dist/utils/setRef.js +10 -0
  64. package/dist/utils/typeGuards/index.d.ts +3 -0
  65. package/dist/utils/typeGuards/isNotNil.d.ts +1 -0
  66. package/dist/utils/typeGuards/isNotNil.js +4 -0
  67. package/dist/utils/typeGuards/isNumber.d.ts +1 -0
  68. package/dist/utils/typeGuards/isNumber.js +4 -0
  69. package/dist/utils/typeGuards/isString.d.ts +1 -0
  70. package/dist/utils/typeGuards/isString.js +4 -0
  71. package/package.json +37 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Koobiq
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # @koobiq/react-core
@@ -0,0 +1,13 @@
1
+ export * from './usePrevious/index.js';
2
+ export * from './useMultiRef/index.js';
3
+ export * from './useIsomorphicEffect/index.js';
4
+ export * from './useMediaQuery';
5
+ export * from './useSsr/index.js';
6
+ export * from './useDOMRef/index.js';
7
+ export * from './useBoolean/index.js';
8
+ export * from './useMutableRef/index.js';
9
+ export * from './useInterval/index.js';
10
+ export * from './useIsFirstRender/index.js';
11
+ export * from './useEventListener/index.js';
12
+ export * from './useResizeObserver/index.js';
13
+ export * from './useElementSize/index.js';
@@ -0,0 +1 @@
1
+ export * from './useBoolean.js';
@@ -0,0 +1,13 @@
1
+ import type { Dispatch, SetStateAction } from 'react';
2
+ export type UseBooleanControllers = {
3
+ /** Set the value to `true` */
4
+ on: () => void;
5
+ /** Set the value to `false` */
6
+ off: () => void;
7
+ /** Toggle the value to the opposite state */
8
+ toggle: () => void;
9
+ /** Set the value to a specific state */
10
+ set: Dispatch<SetStateAction<boolean>>;
11
+ };
12
+ export type UseBooleanReturnValue = [boolean, UseBooleanControllers];
13
+ export declare function useBoolean(defaultValue?: boolean): UseBooleanReturnValue;
@@ -0,0 +1,11 @@
1
+ import { useState, useCallback } from "react";
2
+ function useBoolean(defaultValue = false) {
3
+ const [value, setValue] = useState(defaultValue);
4
+ const on = useCallback(() => setValue(true), []);
5
+ const off = useCallback(() => setValue(false), []);
6
+ const toggle = useCallback(() => setValue((value2) => !value2), []);
7
+ return [value, { on, off, toggle, set: setValue }];
8
+ }
9
+ export {
10
+ useBoolean
11
+ };
@@ -0,0 +1 @@
1
+ export * from './useDOMRef.js';
@@ -0,0 +1,2 @@
1
+ import type { Ref, RefObject } from 'react';
2
+ export declare function useDOMRef<T extends HTMLElement = HTMLElement>(ref?: RefObject<T | null> | Ref<T | null>): RefObject<T>;
@@ -0,0 +1,9 @@
1
+ import { useRef, useImperativeHandle } from "react";
2
+ function useDOMRef(ref) {
3
+ const domRef = useRef(null);
4
+ useImperativeHandle(ref, () => domRef.current);
5
+ return domRef;
6
+ }
7
+ export {
8
+ useDOMRef
9
+ };
@@ -0,0 +1 @@
1
+ export * from './useElementSize';
@@ -0,0 +1,5 @@
1
+ export declare function useElementSize<T extends HTMLElement = any>(options?: ResizeObserverOptions): {
2
+ ref: import("react").RefObject<T>;
3
+ width: number;
4
+ height: number;
5
+ };
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { useResizeObserver } from "../useResizeObserver/useResizeObserver.js";
3
+ function useElementSize(options) {
4
+ const [ref, { width, height }] = useResizeObserver(options);
5
+ return { ref, width, height };
6
+ }
7
+ export {
8
+ useElementSize
9
+ };
@@ -0,0 +1 @@
1
+ export * from './useEventListener';
@@ -0,0 +1,19 @@
1
+ import type { RefObject } from 'react';
2
+ type UseEventListener<T, K, P> = {
3
+ /** Event name, for example, "click". */
4
+ eventName: T;
5
+ /** A handler function that runs as soon as the event happens. */
6
+ handler: K;
7
+ /** The element to which the event will be attached. */
8
+ element?: P;
9
+ /** An additional object with properties. */
10
+ options?: boolean | AddEventListenerOptions;
11
+ /** An indicator of event handler activity, used to improve performance. */
12
+ active?: boolean;
13
+ };
14
+ export declare function useEventListener<K extends keyof MediaQueryListEventMap>({ eventName, handler, element, options, active, }: UseEventListener<K, (event: MediaQueryListEventMap[K]) => void, RefObject<MediaQueryList>>): void;
15
+ export declare function useEventListener<K extends keyof WindowEventMap>({ eventName, handler, element, options, active, }: UseEventListener<K, (event: WindowEventMap[K]) => void, undefined>): void;
16
+ export declare function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = HTMLDivElement>({ eventName, handler, element, options, active, }: UseEventListener<K, (event: HTMLElementEventMap[K]) => void, RefObject<T>>): void;
17
+ export declare function useEventListener<K extends keyof DocumentEventMap>({ eventName, handler, element, options, active, }: UseEventListener<K, (event: DocumentEventMap[K]) => void, RefObject<Document>>): void;
18
+ export declare function useEventListener({ eventName, handler, element, options, active, }: UseEventListener<string, (event: Event | CustomEvent) => void, RefObject<Document | HTMLElement | Window> | undefined>): void;
19
+ export {};
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { useCallback, useEffect } from "react";
3
+ import { useMutableRef } from "../useMutableRef/useMutableRef.js";
4
+ function useEventListener({
5
+ eventName,
6
+ handler,
7
+ element,
8
+ options,
9
+ active = true
10
+ }) {
11
+ const savedListener = useMutableRef(handler);
12
+ const handleEventListener = useCallback((event) => {
13
+ savedListener.current?.(event);
14
+ }, []);
15
+ useEffect(() => {
16
+ if (!active) {
17
+ return void 0;
18
+ }
19
+ const targetElement = element?.current ?? window;
20
+ targetElement?.addEventListener(eventName, handleEventListener, options);
21
+ return () => {
22
+ targetElement?.removeEventListener(
23
+ eventName,
24
+ handleEventListener,
25
+ options
26
+ );
27
+ };
28
+ }, [eventName, element, options, active]);
29
+ }
30
+ export {
31
+ useEventListener
32
+ };
@@ -0,0 +1 @@
1
+ export * from './useInterval';
@@ -0,0 +1,5 @@
1
+ export declare function useInterval(
2
+ /** A callback function that will be triggered at a given interval */
3
+ callback: () => void,
4
+ /** Time interval in milliseconds */
5
+ interval: number | null): void;
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useEffect } from "react";
3
+ import { useMutableRef } from "../useMutableRef/useMutableRef.js";
4
+ function useInterval(callback, interval) {
5
+ const savedCallback = useMutableRef(callback);
6
+ useEffect(() => {
7
+ let intervalId;
8
+ if (interval || interval === 0) {
9
+ intervalId = setInterval(() => savedCallback.current(), interval);
10
+ }
11
+ return () => {
12
+ clearInterval(intervalId);
13
+ };
14
+ }, [interval]);
15
+ }
16
+ export {
17
+ useInterval
18
+ };
@@ -0,0 +1 @@
1
+ export * from './useIsFirstRender';
@@ -0,0 +1 @@
1
+ export declare function useIsFirstRender(): boolean;
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { useRef } from "react";
3
+ function useIsFirstRender() {
4
+ const renderRef = useRef(true);
5
+ if (renderRef.current) {
6
+ renderRef.current = false;
7
+ return true;
8
+ }
9
+ return renderRef.current;
10
+ }
11
+ export {
12
+ useIsFirstRender
13
+ };
@@ -0,0 +1 @@
1
+ export * from './useIsomorphicEffect.js';
@@ -0,0 +1,2 @@
1
+ import { useEffect } from 'react';
2
+ export declare const useIsomorphicEffect: typeof useEffect;
@@ -0,0 +1,6 @@
1
+ import { useLayoutEffect, useEffect } from "react";
2
+ import { isBrowser } from "../../utils/isBrowser.js";
3
+ const useIsomorphicEffect = isBrowser() ? useLayoutEffect : useEffect;
4
+ export {
5
+ useIsomorphicEffect
6
+ };
@@ -0,0 +1 @@
1
+ export * from './useMediaQuery';
@@ -0,0 +1,15 @@
1
+ export type UseMediaQueryOptions = {
2
+ /**
3
+ * As `window.matchMedia()` is unavailable on the server,
4
+ * it returns a default matches during the first mount.
5
+ * @default false
6
+ */
7
+ defaultMatches: boolean[];
8
+ /**
9
+ * The `defaultMatches` property is what will be returned
10
+ * on the first mount if ssr is set to `true`.
11
+ * @default true
12
+ */
13
+ ssr?: boolean;
14
+ };
15
+ export declare function useMediaQuery(query: string[], options?: UseMediaQueryOptions): boolean[];
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { useState, useEffect } from "react";
3
+ function listen(query, callback) {
4
+ query.addEventListener("change", callback);
5
+ return () => query.removeEventListener("change", callback);
6
+ }
7
+ function useMediaQuery(query, options) {
8
+ const { defaultMatches, ssr = true } = options || {};
9
+ const queries = Array.isArray(query) ? query : [query];
10
+ const [value, setValue] = useState(
11
+ () => queries.map((query2, index) => ({
12
+ media: query2,
13
+ matches: !ssr ? window.matchMedia?.(query2)?.matches : defaultMatches?.[index] || false
14
+ }))
15
+ );
16
+ useEffect(() => {
17
+ setValue((prev) => {
18
+ const current = queries.map((query2) => ({
19
+ media: query2,
20
+ matches: window.matchMedia(query2).matches
21
+ }));
22
+ return prev.every(
23
+ (v, i) => v.matches === current[i].matches && v.media === current[i].media
24
+ ) ? prev : current;
25
+ });
26
+ const mql = queries.map((query2) => window.matchMedia(query2));
27
+ const handler = (evt) => {
28
+ setValue(
29
+ (prev) => prev.slice().map((item) => {
30
+ if (item.media === evt.media)
31
+ return { ...item, matches: evt.matches };
32
+ return item;
33
+ })
34
+ );
35
+ };
36
+ const cleanups = mql.map((mq) => listen(mq, handler));
37
+ return () => cleanups.forEach((fn) => fn());
38
+ }, []);
39
+ return value.map((item) => item.matches);
40
+ }
41
+ export {
42
+ useMediaQuery
43
+ };
@@ -0,0 +1 @@
1
+ export * from './useMultiRef.js';
@@ -0,0 +1,4 @@
1
+ import type { Dispatch, SetStateAction, RefCallback, Ref as ReactRef } from 'react';
2
+ type Ref<T> = ReactRef<T> | Dispatch<SetStateAction<T | undefined>> | null;
3
+ export declare function useMultiRef<T>(refs: Array<Ref<T> | undefined>): RefCallback<T> | null;
4
+ export {};
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { useRef, useMemo } from "react";
3
+ import { setRef } from "../../utils/setRef.js";
4
+ function useMultiRef(refs) {
5
+ const arrRefs = useRef(refs);
6
+ return useMemo(() => {
7
+ if (!arrRefs.current.length) {
8
+ return null;
9
+ }
10
+ return (node) => {
11
+ arrRefs.current.forEach((ref) => {
12
+ setRef(ref, node);
13
+ });
14
+ };
15
+ }, [arrRefs]);
16
+ }
17
+ export {
18
+ useMultiRef
19
+ };
@@ -0,0 +1 @@
1
+ export * from './useMutableRef';
@@ -0,0 +1 @@
1
+ export declare function useMutableRef<T>(value: T): import("react").MutableRefObject<T>;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { useRef } from "react";
3
+ function useMutableRef(value) {
4
+ const ref = useRef(value);
5
+ ref.current = value;
6
+ return ref;
7
+ }
8
+ export {
9
+ useMutableRef
10
+ };
@@ -0,0 +1 @@
1
+ export * from './usePrevious.js';
@@ -0,0 +1 @@
1
+ export declare function usePrevious<T>(value: T): T | null;
@@ -0,0 +1,11 @@
1
+ import { useRef, useEffect } from "react";
2
+ function usePrevious(value) {
3
+ const ref = useRef(null);
4
+ useEffect(() => {
5
+ ref.current = value;
6
+ }, [value]);
7
+ return ref.current;
8
+ }
9
+ export {
10
+ usePrevious
11
+ };
@@ -0,0 +1 @@
1
+ export * from './useResizeObserver';
@@ -0,0 +1,3 @@
1
+ type ObserverRect = Omit<DOMRectReadOnly, 'toJSON'>;
2
+ export declare function useResizeObserver<T extends HTMLElement = any>(options?: ResizeObserverOptions): readonly [import("react").RefObject<T>, ObserverRect];
3
+ export {};
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ import { useRef, useState, useMemo, useEffect } from "react";
3
+ const defaultState = {
4
+ x: 0,
5
+ y: 0,
6
+ width: 0,
7
+ height: 0,
8
+ top: 0,
9
+ left: 0,
10
+ bottom: 0,
11
+ right: 0
12
+ };
13
+ function useResizeObserver(options) {
14
+ const frameID = useRef(0);
15
+ const ref = useRef(null);
16
+ const [rect, setRect] = useState(defaultState);
17
+ const observer = useMemo(
18
+ () => typeof window !== "undefined" && typeof ResizeObserver !== "undefined" ? (
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ new ResizeObserver((entries) => {
21
+ const entry = entries[0];
22
+ if (entry) {
23
+ cancelAnimationFrame(frameID.current);
24
+ frameID.current = requestAnimationFrame(() => {
25
+ if (ref.current) {
26
+ setRect(entry.contentRect);
27
+ }
28
+ });
29
+ }
30
+ })
31
+ ) : null,
32
+ []
33
+ );
34
+ useEffect(() => {
35
+ if (ref.current) {
36
+ observer?.observe(ref.current, options);
37
+ }
38
+ return () => {
39
+ observer?.disconnect();
40
+ if (frameID.current) {
41
+ cancelAnimationFrame(frameID.current);
42
+ }
43
+ };
44
+ }, [ref.current]);
45
+ return [ref, rect];
46
+ }
47
+ export {
48
+ useResizeObserver
49
+ };
@@ -0,0 +1 @@
1
+ export * from './useSsr.js';
@@ -0,0 +1,7 @@
1
+ type SsrState = {
2
+ isBrowser: boolean;
3
+ isServer: boolean;
4
+ };
5
+ export type UseSsrReturn = SsrState;
6
+ export declare const useSsr: () => UseSsrReturn;
7
+ export {};
@@ -0,0 +1,15 @@
1
+ import { useState, useEffect } from "react";
2
+ import { isBrowser } from "../../utils/isBrowser.js";
3
+ const useSsr = () => {
4
+ const [browser, setBrowser] = useState(false);
5
+ useEffect(() => {
6
+ setBrowser(isBrowser());
7
+ }, []);
8
+ return {
9
+ isBrowser: browser,
10
+ isServer: !browser
11
+ };
12
+ };
13
+ export {
14
+ useSsr
15
+ };
@@ -0,0 +1,9 @@
1
+ import { useFocusRing, FocusableProvider } from '@react-aria/focus';
2
+ import { useHover, usePress } from '@react-aria/interactions';
3
+ import { mergeProps, filterDOMProps } from '@react-aria/utils';
4
+ import { useToggleState } from '@react-stately/toggle';
5
+ export * from './types/index.js';
6
+ export * from './styles/index.js';
7
+ export * from './hooks/index.js';
8
+ export * from './utils/index.js';
9
+ export { FocusableProvider, mergeProps, useFocusRing, useHover, usePress, useToggleState, filterDOMProps, };
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ import { FocusableProvider, useFocusRing } from "@react-aria/focus";
2
+ import { useHover, usePress } from "@react-aria/interactions";
3
+ import { filterDOMProps, mergeProps } from "@react-aria/utils";
4
+ import { useToggleState } from "@react-stately/toggle";
5
+ import { clsx } from "./styles/clsx.js";
6
+ import { usePrevious } from "./hooks/usePrevious/usePrevious.js";
7
+ import { useMultiRef } from "./hooks/useMultiRef/useMultiRef.js";
8
+ import { useIsomorphicEffect } from "./hooks/useIsomorphicEffect/useIsomorphicEffect.js";
9
+ import { useMediaQuery } from "./hooks/useMediaQuery/useMediaQuery.js";
10
+ import { useSsr } from "./hooks/useSsr/useSsr.js";
11
+ import { useDOMRef } from "./hooks/useDOMRef/useDOMRef.js";
12
+ import { useBoolean } from "./hooks/useBoolean/useBoolean.js";
13
+ import { useMutableRef } from "./hooks/useMutableRef/useMutableRef.js";
14
+ import { useInterval } from "./hooks/useInterval/useInterval.js";
15
+ import { useIsFirstRender } from "./hooks/useIsFirstRender/useIsFirstRender.js";
16
+ import { useEventListener } from "./hooks/useEventListener/useEventListener.js";
17
+ import { useResizeObserver } from "./hooks/useResizeObserver/useResizeObserver.js";
18
+ import { useElementSize } from "./hooks/useElementSize/useElementSize.js";
19
+ import { polymorphicForwardRef } from "./utils/polymorphicForwardRef.js";
20
+ import { isNotNil } from "./utils/typeGuards/isNotNil.js";
21
+ import { isString } from "./utils/typeGuards/isString.js";
22
+ import { isNumber } from "./utils/typeGuards/isNumber.js";
23
+ import { setRef } from "./utils/setRef.js";
24
+ import { isBrowser } from "./utils/isBrowser.js";
25
+ import { capitalizeFirstLetter } from "./utils/capitalizeFirstLetter/capitalizeFirstLetter.js";
26
+ export {
27
+ FocusableProvider,
28
+ capitalizeFirstLetter,
29
+ clsx,
30
+ filterDOMProps,
31
+ isBrowser,
32
+ isNotNil,
33
+ isNumber,
34
+ isString,
35
+ mergeProps,
36
+ polymorphicForwardRef,
37
+ setRef,
38
+ useBoolean,
39
+ useDOMRef,
40
+ useElementSize,
41
+ useEventListener,
42
+ useFocusRing,
43
+ useHover,
44
+ useInterval,
45
+ useIsFirstRender,
46
+ useIsomorphicEffect,
47
+ useMediaQuery,
48
+ useMultiRef,
49
+ useMutableRef,
50
+ usePress,
51
+ usePrevious,
52
+ useResizeObserver,
53
+ useSsr,
54
+ useToggleState
55
+ };
@@ -0,0 +1,3 @@
1
+ type ClassName = string | false | null | undefined;
2
+ export declare function clsx(...classNames: ClassName[]): string;
3
+ export {};
@@ -0,0 +1,6 @@
1
+ function clsx(...classNames) {
2
+ return classNames.filter((className) => Boolean(className)).join(" ");
3
+ }
4
+ export {
5
+ clsx
6
+ };
@@ -0,0 +1 @@
1
+ export * from './clsx.js';
@@ -0,0 +1,3 @@
1
+ type DataAttributeKey = `data-${string}`;
2
+ export type DataAttributeProps = Record<DataAttributeKey, unknown>;
3
+ export {};
@@ -0,0 +1 @@
1
+ export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
@@ -0,0 +1,3 @@
1
+ import type { ComponentPropsWithRef, ElementType } from 'react';
2
+ import type { ExtendableProps } from './ExtendableProps.js';
3
+ export type ExtendableComponentPropsWithRef<Props, Element extends ElementType> = ExtendableProps<Props, ComponentPropsWithRef<Element>>;
@@ -0,0 +1,2 @@
1
+ import type { Merge } from './Merge';
2
+ export type ExtendableProps<OverrideProps = Record<string, unknown>, ExtendedProps = Record<string, unknown>> = Merge<ExtendedProps, OverrideProps>;
@@ -0,0 +1,3 @@
1
+ import type { DistributiveOmit } from './DistributiveOmit';
2
+ export type Merge<A, B> = Omit<A, keyof B> & B;
3
+ export type DistributiveMerge<A, B> = DistributiveOmit<A, keyof B> & B;
@@ -0,0 +1,5 @@
1
+ export * from './Merge';
2
+ export * from './DistributiveOmit';
3
+ export * from './ExtendableProps.js';
4
+ export * from './DataAttributeProps';
5
+ export * from './ExtendableComponentPropsWithRef.js';
@@ -0,0 +1,2 @@
1
+ /** Capitalizes the first character of a word. */
2
+ export declare function capitalizeFirstLetter(string: string): string;
@@ -0,0 +1,6 @@
1
+ function capitalizeFirstLetter(string) {
2
+ return string.charAt(0).toUpperCase() + string.slice(1);
3
+ }
4
+ export {
5
+ capitalizeFirstLetter
6
+ };
@@ -0,0 +1 @@
1
+ export * from './capitalizeFirstLetter';
@@ -0,0 +1,5 @@
1
+ export * from './polymorphicForwardRef';
2
+ export * from './typeGuards/index.js';
3
+ export * from './setRef.js';
4
+ export * from './isBrowser.js';
5
+ export * from './capitalizeFirstLetter';
@@ -0,0 +1 @@
1
+ export declare const isBrowser: () => boolean;
@@ -0,0 +1,6 @@
1
+ const isBrowser = () => Boolean(
2
+ typeof window !== "undefined" && window.document && window.document.createElement
3
+ );
4
+ export {
5
+ isBrowser
6
+ };
@@ -0,0 +1,13 @@
1
+ import type { ElementType, ReactElement, ComponentPropsWithRef, ForwardRefRenderFunction, ForwardRefExoticComponent } from 'react';
2
+ import type { DistributiveMerge, Merge } from '../types';
3
+ export type AsProps<Component extends ElementType, PermanentProps extends object, ComponentProps extends object> = DistributiveMerge<ComponentProps, PermanentProps & {
4
+ as?: Component;
5
+ }>;
6
+ export type PolymorphicWithRef<Default extends OnlyAs, Props extends object = object, OnlyAs extends ElementType = ElementType> = <T extends OnlyAs = Default>(props: AsProps<T, Props, ComponentPropsWithRef<T>>) => ReactElement | null;
7
+ export type PolyForwardComponent<Default extends OnlyAs, Props extends object = object, OnlyAs extends ElementType = ElementType> = Merge<ForwardRefExoticComponent<Merge<ComponentPropsWithRef<Default>, Props & {
8
+ as?: Default;
9
+ }>>, PolymorphicWithRef<Default, Props, OnlyAs>>;
10
+ export type PolyRefFunction = <Default extends OnlyAs, Props extends object = object, OnlyAs extends ElementType = ElementType>(Component: ForwardRefRenderFunction<any, Props & {
11
+ as?: OnlyAs;
12
+ }>) => PolyForwardComponent<Default, Props, OnlyAs>;
13
+ export declare const polymorphicForwardRef: PolyRefFunction;
@@ -0,0 +1,5 @@
1
+ import { forwardRef } from "react";
2
+ const polymorphicForwardRef = forwardRef;
3
+ export {
4
+ polymorphicForwardRef
5
+ };
@@ -0,0 +1,4 @@
1
+ import type { Dispatch, SetStateAction, Ref as ReactRef } from 'react';
2
+ type Ref<T> = ReactRef<T> | Dispatch<SetStateAction<T | undefined>> | null;
3
+ export declare const setRef: <T>(ref: Ref<T> | undefined, value: T) => void;
4
+ export {};
@@ -0,0 +1,10 @@
1
+ const setRef = (ref, value) => {
2
+ if (typeof ref === "function") {
3
+ ref(value);
4
+ } else if (ref) {
5
+ ref.current = value;
6
+ }
7
+ };
8
+ export {
9
+ setRef
10
+ };
@@ -0,0 +1,3 @@
1
+ export * from './isNotNil.js';
2
+ export * from './isString.js';
3
+ export * from './isNumber.js';
@@ -0,0 +1 @@
1
+ export declare const isNotNil: <T>(p: T) => p is Exclude<T, undefined | null>;
@@ -0,0 +1,4 @@
1
+ const isNotNil = (p) => p !== void 0 && p !== null;
2
+ export {
3
+ isNotNil
4
+ };
@@ -0,0 +1 @@
1
+ export declare const isNumber: (data: unknown) => data is number;
@@ -0,0 +1,4 @@
1
+ const isNumber = (data) => typeof data === "number";
2
+ export {
3
+ isNumber
4
+ };
@@ -0,0 +1 @@
1
+ export declare const isString: (data: unknown) => data is string;
@@ -0,0 +1,4 @@
1
+ const isString = (data) => typeof data === "string";
2
+ export {
3
+ isString
4
+ };
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@koobiq/react-core",
3
+ "version": "0.0.1-beta.1",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "default": "./dist/index.js"
10
+ }
11
+ },
12
+ "type": "module",
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "sideEffects": false,
20
+ "dependencies": {
21
+ "@react-aria/focus": "^3.18.0",
22
+ "@react-aria/interactions": "^3.21.0",
23
+ "@react-aria/utils": "^3.25.0",
24
+ "@react-stately/toggle": "^3.7.0"
25
+ },
26
+ "peerDependencies": {
27
+ "react": "18.x || 19.x",
28
+ "react-dom": "18.x || 19.x"
29
+ },
30
+ "scripts": {
31
+ "clean": "rimraf dist && rimraf node_modules && rimraf .turbo",
32
+ "lint:js": "eslint --ext .ts,.tsx src --fix",
33
+ "lint": "pnpm lint:js",
34
+ "build": "vite build && tsc -p tsconfig.build.json && rm -rf dist/node_modules",
35
+ "type-check": "tsc --noEmit --pretty"
36
+ }
37
+ }