@mediamonks/react-kit 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_utils/childrenAreEqual.d.ts +2 -2
- package/dist/gsap/components/SplitTextWrapper/SplitTextWrapper.d.ts +5 -9
- package/dist/gsap/components/SplitTextWrapper/SplitTextWrapper.js +8 -8
- package/dist/gsap/hooks/useAnimation/useAnimation.js +3 -1
- package/dist/gsap/hooks/useFlip/useFlip.d.ts +2 -2
- package/dist/gsap/hooks/useFlip/useFlip.js +3 -1
- package/dist/hocs/ensuredForwardRef/ensuredForwardRef.d.ts +6 -0
- package/dist/hocs/ensuredForwardRef/ensuredForwardRef.js +4 -0
- package/dist/hooks/useIntersectionObserver/useIntersectionObserver.js +3 -1
- package/dist/hooks/useInterval/useInterval.js +3 -1
- package/dist/hooks/useMediaDuration/useMediaDuration.d.ts +2 -2
- package/dist/hooks/useObjectRef/useObjectRef.d.ts +18 -0
- package/dist/hooks/useObjectRef/useObjectRef.js +35 -0
- package/dist/hooks/useRefs/useRefs.types.d.ts +1 -0
- package/dist/utils/arrayRef/arrayRef.d.ts +2 -2
- package/package.json +2 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type ReactElement
|
|
2
|
-
export declare function childrenAreEqual(previousChildren: ReactElement |
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
export declare function childrenAreEqual(previousChildren: ReactElement | null, nextChildren: ReactElement | null): boolean;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/// <reference types="gsap/types/split-text.js" />
|
|
2
2
|
import SplitText from 'gsap/SplitText';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ComponentPropsWithoutRef, type JSX, type JSXElementConstructor, type ReactNode, type RefObject } from 'react';
|
|
4
4
|
/**
|
|
5
5
|
* Allowed as prop values
|
|
6
6
|
*/
|
|
7
|
-
type KnownTarget =
|
|
7
|
+
type KnownTarget = keyof JSX.IntrinsicElements | JSXElementConstructor<any>;
|
|
8
8
|
type SplitTextWrapperProps<T extends KnownTarget> = {
|
|
9
|
+
ref: RefObject<SplitText>;
|
|
9
10
|
/**
|
|
10
11
|
* The SplitText variables
|
|
11
12
|
* @link https://greensock.com/docs/v3/Plugins/SplitText
|
|
@@ -19,11 +20,6 @@ type SplitTextWrapperProps<T extends KnownTarget> = {
|
|
|
19
20
|
* Split the first element child of the element passed
|
|
20
21
|
*/
|
|
21
22
|
splitFirstElementChild?: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
* Polymorphic component type, necessary to get all the attributes/props for the
|
|
25
|
-
* as prop component
|
|
26
|
-
*/
|
|
27
|
-
type SplitTextWrapperComponent = <T extends KnownTarget = 'div'>(props: SplitTextWrapperProps<T> & Omit<ComponentProps<T>, keyof SplitTextWrapperProps<T> | 'ref'> & RefAttributes<SplitText | null>) => ReactElement;
|
|
28
|
-
export declare const SplitTextWrapper: SplitTextWrapperComponent;
|
|
23
|
+
} & ComponentPropsWithoutRef<T>;
|
|
24
|
+
export declare function SplitTextWrapper<T extends KnownTarget>({ variables, as, children, splitFirstElementChild, ref, ...props }: SplitTextWrapperProps<T>): ReactNode;
|
|
29
25
|
export {};
|
|
@@ -2,31 +2,31 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import gsap from 'gsap';
|
|
3
3
|
import SplitText from 'gsap/SplitText';
|
|
4
4
|
import { renderToString } from 'react-dom/server';
|
|
5
|
-
import {
|
|
5
|
+
import { useObjectRef } from '../../../hooks/useObjectRef/useObjectRef.js';
|
|
6
6
|
if (typeof window !== 'undefined') {
|
|
7
7
|
gsap.registerPlugin(SplitText);
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
export function SplitTextWrapper({ variables = {}, as, children, splitFirstElementChild = false, ref, ...props }) {
|
|
10
|
+
const objectRef = useObjectRef(ref);
|
|
11
11
|
/**
|
|
12
12
|
* Not using useCallback on purpose so that a new SplitText instance is
|
|
13
13
|
* created whenever this component rerenders the children
|
|
14
14
|
*/
|
|
15
|
-
const onRef =
|
|
16
|
-
if (
|
|
15
|
+
const onRef = (element) => {
|
|
16
|
+
if (objectRef.current && 'isSplit' in objectRef.current && objectRef.current.isSplit) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
if (splitFirstElementChild && element.childElementCount > 1) {
|
|
20
20
|
// eslint-disable-next-line no-console
|
|
21
21
|
console.warn("Split text wrapper should only contain 1 element when 'splitFirstElementChild' is set to true");
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
objectRef.current = new SplitText(splitFirstElementChild ? element.firstElementChild : element, variables);
|
|
24
24
|
};
|
|
25
|
-
const Component =
|
|
25
|
+
const Component = as ?? 'div';
|
|
26
26
|
return (_jsx(Component, { ...props, dangerouslySetInnerHTML: props.dangerouslySetInnerHTML ?? {
|
|
27
27
|
// eslint-disable-next-line @typescript-eslint/naming-convention, react/jsx-no-useless-fragment
|
|
28
28
|
__html: renderToString(_jsx(_Fragment, { children: children })),
|
|
29
29
|
},
|
|
30
30
|
// eslint-disable-next-line react/jsx-no-bind
|
|
31
31
|
ref: onRef }));
|
|
32
|
-
}
|
|
32
|
+
}
|
|
@@ -4,7 +4,9 @@ import { useCallback, useEffect, useRef } from 'react';
|
|
|
4
4
|
* unmounted or when a new callback function is provided.
|
|
5
5
|
*/
|
|
6
6
|
export function useAnimation(callback, dependencies) {
|
|
7
|
-
const animation = useRef(
|
|
7
|
+
const animation = useRef(
|
|
8
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
9
|
+
undefined);
|
|
8
10
|
// eslint-disable-next-line react-hooks/exhaustive-deps, no-underscore-dangle
|
|
9
11
|
const _callback = useCallback(callback, dependencies);
|
|
10
12
|
useEffect(() => {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
2
|
import { type Unreffable } from '../../../utils/unref/unref.js';
|
|
3
|
-
export declare function useFlip(ref: Unreffable<HTMLElement | null>, flipStateVariables?: Flip.FromToVars):
|
|
3
|
+
export declare function useFlip(ref: Unreffable<HTMLElement | null>, flipStateVariables?: Flip.FromToVars): RefObject<Flip.FlipState | undefined>;
|
|
@@ -6,7 +6,9 @@ if (typeof window !== 'undefined') {
|
|
|
6
6
|
gsap.registerPlugin(Flip);
|
|
7
7
|
}
|
|
8
8
|
export function useFlip(ref, flipStateVariables = {}) {
|
|
9
|
-
const flipStateRef = useRef(
|
|
9
|
+
const flipStateRef = useRef(
|
|
10
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
11
|
+
undefined);
|
|
10
12
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
11
13
|
if (globalThis.window !== undefined) {
|
|
12
14
|
flipStateRef.current = Flip.getState(unref(ref));
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { type ForwardRefExoticComponent, type MutableRefObject, type PropsWithoutRef, type ReactElement, type RefAttributes } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated use `useObjectRef` instead
|
|
4
|
+
*/
|
|
2
5
|
export interface EnsuredForwardRefRenderFunction<T, P = Record<string | number | symbol, unknown>> {
|
|
3
6
|
(props: P, ref: MutableRefObject<T | null>): ReactElement | null;
|
|
4
7
|
displayName?: string | undefined;
|
|
@@ -8,4 +11,7 @@ export interface EnsuredForwardRefRenderFunction<T, P = Record<string | number |
|
|
|
8
11
|
defaultProps?: never;
|
|
9
12
|
propTypes?: never;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated use `useObjectRef` instead
|
|
16
|
+
*/
|
|
11
17
|
export declare function ensuredForwardRef<T, P = Record<string | number | symbol, unknown>>(Component: EnsuredForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { createRef, forwardRef, useMemo, } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated use `useObjectRef` instead
|
|
4
|
+
*/
|
|
2
5
|
export function ensuredForwardRef(
|
|
3
6
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
4
7
|
Component) {
|
|
@@ -26,6 +29,7 @@ Component) {
|
|
|
26
29
|
},
|
|
27
30
|
});
|
|
28
31
|
}, [ref]);
|
|
32
|
+
// @ts-expect-error - deprecated in React 19
|
|
29
33
|
return Component(props, refObject);
|
|
30
34
|
});
|
|
31
35
|
}
|
|
@@ -15,7 +15,9 @@ import { useRefValue } from '../useRefValue/useRefValue.js';
|
|
|
15
15
|
*/
|
|
16
16
|
export function useIntersectionObserver(targetOrTargets, callback, options) {
|
|
17
17
|
const callbackRef = useRefValue(callback);
|
|
18
|
-
const intersectionObserverInstance = useClientSideValue(() => new IntersectionObserver((entries, observer) =>
|
|
18
|
+
const intersectionObserverInstance = useClientSideValue(() => new IntersectionObserver((entries, observer) => {
|
|
19
|
+
callbackRef.current?.(entries, observer);
|
|
20
|
+
}, options));
|
|
19
21
|
useEffect(() => {
|
|
20
22
|
const targets = Array.isArray(targetOrTargets.current)
|
|
21
23
|
? targetOrTargets.current
|
|
@@ -9,7 +9,9 @@ import { useRefValue } from '../useRefValue/useRefValue.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export function useInterval(callback, ms, enabled = true) {
|
|
11
11
|
const callbackRef = useRefValue(callback);
|
|
12
|
-
const intervalRef = useRef(
|
|
12
|
+
const intervalRef = useRef(
|
|
13
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
14
|
+
undefined);
|
|
13
15
|
useEffect(() => {
|
|
14
16
|
if (!enabled) {
|
|
15
17
|
clearInterval(intervalRef.current);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* Retrieves the duration of the audio / video file in seconds.
|
|
4
4
|
*/
|
|
5
|
-
export declare function useMediaDuration(mediaElementRef:
|
|
5
|
+
export declare function useMediaDuration(mediaElementRef: RefObject<HTMLMediaElement | null>): number;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Ref, type RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A React hook that creates a memoized object reference which can handle both RefObject and function refs.
|
|
4
|
+
* This hook provides a unified way to work with different types of React refs.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* // Using with RefObject
|
|
9
|
+
* const elementRef = useRef<HTMLDivElement>(null);
|
|
10
|
+
* const objRef = useObjectRef(elementRef);
|
|
11
|
+
*
|
|
12
|
+
* // Using with function ref
|
|
13
|
+
* const objRef = useObjectRef((element) => {
|
|
14
|
+
* console.log('Element changed:', element);
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function useObjectRef<T>(ref?: Ref<T>): RefObject<T | null>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createRef, useMemo } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A React hook that creates a memoized object reference which can handle both RefObject and function refs.
|
|
4
|
+
* This hook provides a unified way to work with different types of React refs.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* // Using with RefObject
|
|
9
|
+
* const elementRef = useRef<HTMLDivElement>(null);
|
|
10
|
+
* const objRef = useObjectRef(elementRef);
|
|
11
|
+
*
|
|
12
|
+
* // Using with function ref
|
|
13
|
+
* const objRef = useObjectRef((element) => {
|
|
14
|
+
* console.log('Element changed:', element);
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function useObjectRef(ref) {
|
|
19
|
+
return useMemo(() => {
|
|
20
|
+
if (ref !== null && ref !== undefined && 'current' in ref) {
|
|
21
|
+
return ref;
|
|
22
|
+
}
|
|
23
|
+
return new Proxy(createRef(), {
|
|
24
|
+
set(target, prop, newValue) {
|
|
25
|
+
if (prop !== 'current') {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
target.current = newValue;
|
|
29
|
+
// Call ref function when it exists
|
|
30
|
+
ref?.(newValue);
|
|
31
|
+
return true;
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}, [ref]);
|
|
35
|
+
}
|
|
@@ -8,6 +8,7 @@ export type Refs<T extends UnknownRecord = UnknownRecord> = {
|
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
10
|
* Type utility to create an object type where all values are MutableRefObjects
|
|
11
|
+
* @deprecated use `Refs` instead
|
|
11
12
|
*/
|
|
12
13
|
export type MutableRefs<T extends UnknownRecord = UnknownRecord> = {
|
|
13
14
|
[P in keyof T]: MutableRefObject<T[P] | null>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="lodash" resolution-mode="require"/>
|
|
2
|
-
import type {
|
|
2
|
+
import type { RefObject } from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* Helper to set element in RefObject<Array>
|
|
5
5
|
*/
|
|
6
|
-
declare function arrayRefInternal<T extends
|
|
6
|
+
declare function arrayRefInternal<T extends RefObject<Array<unknown> | null>>(ref: T, index: number): (element: NonNullable<T['current']>[number]) => void;
|
|
7
7
|
export declare const arrayRef: typeof arrayRefInternal & import("lodash").MemoizedFunction;
|
|
8
8
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mediamonks/react-kit",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A collection of React hooks, components, utilities that we use at Media.Monks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
"@storybook/types": "^8.5.2",
|
|
73
73
|
"@testing-library/react": "^16.2.0",
|
|
74
74
|
"@types/lodash-es": "^4.17.11",
|
|
75
|
-
"@types/react": "^18.0.25",
|
|
76
75
|
"@vitejs/plugin-react": "^4.0.0",
|
|
77
76
|
"concurrently": "^8.2.2",
|
|
78
77
|
"eslint": "^8.28.0",
|
|
@@ -90,7 +89,7 @@
|
|
|
90
89
|
"storybook": "^8.5.2",
|
|
91
90
|
"ts-node": "^10.9.1",
|
|
92
91
|
"typescript": "^5.0.2",
|
|
93
|
-
"vitest": "^0.
|
|
92
|
+
"vitest": "^3.0.5",
|
|
94
93
|
"wait-on": "^7.1.0"
|
|
95
94
|
},
|
|
96
95
|
"dependencies": {
|