@zayne-labs/ui-react 0.10.29 → 0.10.30
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/esm/common/await/index.d.ts +4 -4
- package/dist/esm/common/error-boundary/index.d.ts +1 -1
- package/dist/esm/common/for/index.d.ts +2 -2
- package/dist/esm/common/presence/index.d.ts +15 -3
- package/dist/esm/common/presence/index.js +1 -1
- package/dist/esm/common/slot/index.d.ts +2 -2
- package/dist/esm/common/suspense-with-boundary/index.d.ts +2 -2
- package/dist/esm/common/teleport/index.js +8 -5
- package/dist/esm/common/teleport/index.js.map +1 -1
- package/dist/esm/{index-b07BOI6k.d.ts → index-BFkVXsFG.d.ts} +4 -4
- package/dist/esm/{index-VaH0JUpk.d.ts → index-D5O2PoOf.d.ts} +3 -3
- package/dist/esm/{presence-CAQElNtY.js → presence-CzmCEhXS.js} +67 -45
- package/dist/esm/presence-CzmCEhXS.js.map +1 -0
- package/dist/esm/ui/carousel/index.d.ts +9 -9
- package/dist/esm/ui/drag-scroll/index.js +13 -8
- package/dist/esm/ui/drag-scroll/index.js.map +1 -1
- package/dist/esm/ui/drop-zone/index.d.ts +3 -1
- package/dist/esm/ui/drop-zone/index.js +9 -7
- package/dist/esm/ui/drop-zone/index.js.map +1 -1
- package/dist/esm/ui/form/index.js +5 -2
- package/dist/esm/ui/form/index.js.map +1 -1
- package/dist/style.css +5 -0
- package/package.json +1 -1
- package/dist/esm/presence-CAQElNtY.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ErrorBoundaryProps } from "../../index-
|
|
2
|
-
import { SuspenseWithBoundaryProps } from "../../index-
|
|
1
|
+
import { ErrorBoundaryProps } from "../../index-D5O2PoOf.js";
|
|
2
|
+
import { SuspenseWithBoundaryProps } from "../../index-BFkVXsFG.js";
|
|
3
3
|
import { GetSlotComponentProps } from "@zayne-labs/toolkit-react/utils";
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import * as
|
|
5
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/components/common/await/await.d.ts
|
|
8
8
|
type RenderPropFn<TValue> = (result: TValue) => React.ReactNode;
|
|
@@ -14,7 +14,7 @@ type AwaitRootProps<TValue> = Pick<SuspenseWithBoundaryProps, "errorFallback" |
|
|
|
14
14
|
withErrorBoundary?: boolean;
|
|
15
15
|
withSuspense?: boolean;
|
|
16
16
|
};
|
|
17
|
-
declare function AwaitRoot<TValue>(props: AwaitRootProps<TValue>):
|
|
17
|
+
declare function AwaitRoot<TValue>(props: AwaitRootProps<TValue>): react_jsx_runtime0.JSX.Element;
|
|
18
18
|
type AwaitSuccessProps<TValue = unknown> = GetSlotComponentProps<"default", ChildrenType<TValue>>;
|
|
19
19
|
declare function AwaitSuccess<TPromiseOrValue, TValue = Awaited<TPromiseOrValue>>(props: Pick<AwaitSuccessProps<TValue>, "children">): React.ReactNode;
|
|
20
20
|
type AwaitErrorProps = GetSlotComponentProps<"error", ErrorBoundaryProps["fallback"]>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ErrorBoundary, ErrorBoundaryContextType, ErrorBoundaryProps, FallbackProps, useErrorBoundary, useErrorBoundaryContext } from "../../index-
|
|
1
|
+
import { ErrorBoundary, ErrorBoundaryContextType, ErrorBoundaryProps, FallbackProps, useErrorBoundary, useErrorBoundaryContext } from "../../index-D5O2PoOf.js";
|
|
2
2
|
export { ErrorBoundary, ErrorBoundaryContextType, ErrorBoundaryProps, FallbackProps, useErrorBoundary, useErrorBoundaryContext };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DiscriminatedRenderItemProps, PolymorphicPropsStrict } from "@zayne-labs/toolkit-react/utils";
|
|
2
2
|
import { Prettify } from "@zayne-labs/toolkit-type-helpers";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import * as
|
|
4
|
+
import * as react_jsx_runtime17 from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/components/common/for/for.d.ts
|
|
7
7
|
type ArrayOrNumber = number | readonly unknown[];
|
|
@@ -15,7 +15,7 @@ type ForProps<TArray extends ArrayOrNumber> = Prettify<{
|
|
|
15
15
|
declare function For<const TArray extends ArrayOrNumber>(props: ForProps<TArray>): string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null;
|
|
16
16
|
declare function ForWithWrapper<const TArray extends ArrayOrNumber, TElement extends React.ElementType = "ul">(props: PolymorphicPropsStrict<TElement, ForProps<TArray>> & {
|
|
17
17
|
displayFallBackWhenEmpty?: boolean;
|
|
18
|
-
}): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> |
|
|
18
|
+
}): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime17.JSX.Element | null;
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/components/common/for/getElementList.d.ts
|
|
21
21
|
type GetElementListResult<TVariant extends "base" | "withWrapper"> = TVariant extends "base" ? [typeof For] : [typeof ForWithWrapper];
|
|
@@ -4,6 +4,20 @@ import * as React from "react";
|
|
|
4
4
|
type UsePresenceOptions = {
|
|
5
5
|
onExitComplete?: () => void;
|
|
6
6
|
present: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* @default "animation"
|
|
9
|
+
*/
|
|
10
|
+
variant?: "animation" | "transition";
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* React hook that provides the ability to animate the mount/unmount of a component.
|
|
14
|
+
* @see https://github.com/radix-ui/primitives/blob/main/packages/react/presence/src/presence.tsx
|
|
15
|
+
*/
|
|
16
|
+
declare const usePresence: (options: UsePresenceOptions) => {
|
|
17
|
+
isPresent: boolean;
|
|
18
|
+
isPresentOrIsTransitionComplete: boolean;
|
|
19
|
+
ref: (refNode: HTMLElement | null) => void;
|
|
20
|
+
shouldStartTransition: boolean;
|
|
7
21
|
};
|
|
8
22
|
//#endregion
|
|
9
23
|
//#region src/components/common/presence/presence.d.ts
|
|
@@ -11,9 +25,7 @@ type RefProp = {
|
|
|
11
25
|
ref?: React.Ref<HTMLElement>;
|
|
12
26
|
};
|
|
13
27
|
type PresenceProps = UsePresenceOptions & {
|
|
14
|
-
children?: React.ReactElement<RefProp> | ((props:
|
|
15
|
-
isPresent: boolean;
|
|
16
|
-
}) => React.ReactElement<RefProp>);
|
|
28
|
+
children?: React.ReactElement<RefProp> | ((props: Omit<ReturnType<typeof usePresence>, "ref">) => React.ReactElement<RefProp>);
|
|
17
29
|
forceMount?: boolean;
|
|
18
30
|
};
|
|
19
31
|
declare function Presence(props: PresenceProps): React.ReactElement<RefProp, string | React.JSXElementConstructor<any>> | null | undefined;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { InferProps } from "@zayne-labs/toolkit-react/utils";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime16 from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/components/common/slot/slot.d.ts
|
|
6
6
|
type SlotProps = InferProps<HTMLElement>;
|
|
7
|
-
declare function SlotRoot(props: SlotProps):
|
|
7
|
+
declare function SlotRoot(props: SlotProps): react_jsx_runtime16.JSX.Element | null;
|
|
8
8
|
declare function SlotSlottable({
|
|
9
9
|
children
|
|
10
10
|
}: Pick<SlotProps, "children">): React.ReactNode;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "../../index-
|
|
2
|
-
import { SuspenseWithBoundary, SuspenseWithBoundaryProps } from "../../index-
|
|
1
|
+
import "../../index-D5O2PoOf.js";
|
|
2
|
+
import { SuspenseWithBoundary, SuspenseWithBoundaryProps } from "../../index-BFkVXsFG.js";
|
|
3
3
|
export { SuspenseWithBoundary, SuspenseWithBoundaryProps };
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import { isString } from "@zayne-labs/toolkit-type-helpers";
|
|
2
|
-
import {
|
|
2
|
+
import { useEffectEvent, useInsertionEffect, useState } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
|
|
5
5
|
//#region src/components/common/teleport/teleport.tsx
|
|
6
6
|
function Teleport(props) {
|
|
7
7
|
const { children, insertPosition, to } = props;
|
|
8
8
|
const [portalContainer, setPortalContainer] = useState(null);
|
|
9
|
-
|
|
9
|
+
const updatePortalContainer = useEffectEvent((destination) => {
|
|
10
|
+
setPortalContainer(destination);
|
|
11
|
+
});
|
|
12
|
+
useInsertionEffect(() => {
|
|
10
13
|
if (!to) return;
|
|
11
14
|
if (insertPosition) return;
|
|
12
15
|
const destination = isString(to) ? document.querySelector(to) : to;
|
|
13
|
-
destination &&
|
|
16
|
+
destination && updatePortalContainer(destination);
|
|
14
17
|
}, [to, insertPosition]);
|
|
15
|
-
|
|
18
|
+
useInsertionEffect(() => {
|
|
16
19
|
if (!to) return;
|
|
17
20
|
if (!insertPosition) return;
|
|
18
21
|
const destination = isString(to) ? document.querySelector(to) : to;
|
|
19
22
|
const tempWrapper = document.createElement("div");
|
|
20
23
|
tempWrapper.style.display = "contents";
|
|
21
24
|
destination?.insertAdjacentElement(insertPosition, tempWrapper);
|
|
22
|
-
|
|
25
|
+
updatePortalContainer(tempWrapper);
|
|
23
26
|
return () => {
|
|
24
27
|
tempWrapper.remove();
|
|
25
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/common/teleport/teleport.tsx"],"sourcesContent":["\"use client\";\n\nimport { type AnyString, isString } from \"@zayne-labs/toolkit-type-helpers\";\nimport * as React from \"react\";\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/common/teleport/teleport.tsx"],"sourcesContent":["\"use client\";\n\nimport { type AnyString, isString } from \"@zayne-labs/toolkit-type-helpers\";\nimport * as React from \"react\";\nimport { useEffectEvent, useInsertionEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\ntype ValidHtmlTags = keyof HTMLElementTagNameMap;\n\ntype PortalProps = {\n\tchildren: React.ReactNode;\n\tinsertPosition?: InsertPosition;\n\tto: AnyString | HTMLElement | ValidHtmlTags | null;\n};\n\nfunction Teleport(props: PortalProps) {\n\tconst { children, insertPosition, to } = props;\n\n\tconst [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n\n\tconst updatePortalContainer = useEffectEvent((destination: HTMLElement | null) => {\n\t\tsetPortalContainer(destination);\n\t});\n\n\tuseInsertionEffect(() => {\n\t\tif (!to) return;\n\n\t\tif (insertPosition) return;\n\n\t\tconst destination = isString(to) ? document.querySelector<HTMLElement>(to) : to;\n\n\t\tdestination && updatePortalContainer(destination);\n\t}, [to, insertPosition]);\n\n\tuseInsertionEffect(() => {\n\t\tif (!to) return;\n\n\t\tif (!insertPosition) return;\n\n\t\tconst destination = isString(to) ? document.querySelector<HTMLElement>(to) : to;\n\n\t\tconst tempWrapper = document.createElement(\"div\");\n\t\ttempWrapper.style.display = \"contents\";\n\n\t\tdestination?.insertAdjacentElement(insertPosition, tempWrapper);\n\n\t\tupdatePortalContainer(tempWrapper);\n\n\t\treturn () => {\n\t\t\ttempWrapper.remove();\n\t\t};\n\t}, [to, insertPosition]);\n\n\treturn portalContainer && createPortal(children, portalContainer);\n}\n\nexport { Teleport };\n"],"mappings":";;;;;AAeA,SAAS,SAAS,OAAoB;CACrC,MAAM,EAAE,UAAU,gBAAgB,OAAO;CAEzC,MAAM,CAAC,iBAAiB,sBAAsB,SAA6B,KAAK;CAEhF,MAAM,wBAAwB,gBAAgB,gBAAoC;AACjF,qBAAmB,YAAY;GAC9B;AAEF,0BAAyB;AACxB,MAAI,CAAC,GAAI;AAET,MAAI,eAAgB;EAEpB,MAAM,cAAc,SAAS,GAAG,GAAG,SAAS,cAA2B,GAAG,GAAG;AAE7E,iBAAe,sBAAsB,YAAY;IAC/C,CAAC,IAAI,eAAe,CAAC;AAExB,0BAAyB;AACxB,MAAI,CAAC,GAAI;AAET,MAAI,CAAC,eAAgB;EAErB,MAAM,cAAc,SAAS,GAAG,GAAG,SAAS,cAA2B,GAAG,GAAG;EAE7E,MAAM,cAAc,SAAS,cAAc,MAAM;AACjD,cAAY,MAAM,UAAU;AAE5B,eAAa,sBAAsB,gBAAgB,YAAY;AAE/D,wBAAsB,YAAY;AAElC,eAAa;AACZ,eAAY,QAAQ;;IAEnB,CAAC,IAAI,eAAe,CAAC;AAExB,QAAO,mBAAmB,aAAa,UAAU,gBAAgB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ErrorBoundaryProps } from "./index-
|
|
1
|
+
import { ErrorBoundaryProps } from "./index-D5O2PoOf.js";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/components/common/suspense-with-boundary/suspense-with-boundary.d.ts
|
|
6
6
|
type SuspenseWithBoundaryProps = {
|
|
@@ -8,7 +8,7 @@ type SuspenseWithBoundaryProps = {
|
|
|
8
8
|
errorFallback?: ErrorBoundaryProps["fallback"];
|
|
9
9
|
fallback?: React.ReactNode;
|
|
10
10
|
};
|
|
11
|
-
declare function SuspenseWithBoundary(props: SuspenseWithBoundaryProps):
|
|
11
|
+
declare function SuspenseWithBoundary(props: SuspenseWithBoundaryProps): react_jsx_runtime0.JSX.Element;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { SuspenseWithBoundary, SuspenseWithBoundaryProps };
|
|
14
|
-
//# sourceMappingURL=index-
|
|
14
|
+
//# sourceMappingURL=index-BFkVXsFG.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React$1 from "react";
|
|
2
2
|
import { Component } from "react";
|
|
3
3
|
import * as _zayne_labs_toolkit_react0 from "@zayne-labs/toolkit-react";
|
|
4
|
-
import * as
|
|
4
|
+
import * as react_jsx_runtime18 from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/components/common/error-boundary/types.d.ts
|
|
7
7
|
type FallbackProps = {
|
|
@@ -49,7 +49,7 @@ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryS
|
|
|
49
49
|
};
|
|
50
50
|
componentDidCatch(error: Error, info: React$1.ErrorInfo): void;
|
|
51
51
|
componentDidUpdate(prevProps: ErrorBoundaryProps, prevState: ErrorBoundaryState): void;
|
|
52
|
-
render():
|
|
52
|
+
render(): react_jsx_runtime18.JSX.Element;
|
|
53
53
|
}
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/components/common/error-boundary/error-boundary-context.d.ts
|
|
@@ -67,4 +67,4 @@ declare const useErrorBoundary: <TError extends Error>() => {
|
|
|
67
67
|
};
|
|
68
68
|
//#endregion
|
|
69
69
|
export { ErrorBoundary, type ErrorBoundaryContextType, ErrorBoundaryProps, FallbackProps, useErrorBoundary, useErrorBoundaryContext };
|
|
70
|
-
//# sourceMappingURL=index-
|
|
70
|
+
//# sourceMappingURL=index-D5O2PoOf.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isFunction } from "@zayne-labs/toolkit-type-helpers";
|
|
2
2
|
import { Children, cloneElement, useEffect, useLayoutEffect, useReducer, useRef, useState } from "react";
|
|
3
|
-
import { useCallbackRef, useComposeRefs } from "@zayne-labs/toolkit-react";
|
|
3
|
+
import { useCallbackRef, useComposeRefs, useToggle } from "@zayne-labs/toolkit-react";
|
|
4
4
|
import { on } from "@zayne-labs/toolkit-core";
|
|
5
5
|
|
|
6
6
|
//#region src/components/common/presence/use-presence.ts
|
|
@@ -16,14 +16,17 @@ const getAnimationName = (styles) => styles?.animationName ?? "none";
|
|
|
16
16
|
* @see https://github.com/radix-ui/primitives/blob/main/packages/react/presence/src/presence.tsx
|
|
17
17
|
*/
|
|
18
18
|
const usePresence = (options) => {
|
|
19
|
-
const { onExitComplete, present } = options;
|
|
20
|
-
const
|
|
19
|
+
const { onExitComplete, present: presentProp, variant = "animation" } = options;
|
|
20
|
+
const stableOnExitComplete = useCallbackRef(onExitComplete);
|
|
21
21
|
const [node, setNode] = useState(null);
|
|
22
|
+
const [hasTransitioned, toggleHasTransitioned] = useToggle(false);
|
|
22
23
|
const stylesRef = useRef(null);
|
|
23
|
-
const
|
|
24
|
-
|
|
24
|
+
const prevNodeStateRef = useRef({
|
|
25
|
+
prevAnimationName: "none",
|
|
26
|
+
prevPresent: presentProp
|
|
27
|
+
});
|
|
25
28
|
const [state, send] = useStateMachine({
|
|
26
|
-
initial:
|
|
29
|
+
initial: presentProp ? "mounted" : "unmounted",
|
|
27
30
|
states: {
|
|
28
31
|
mounted: {
|
|
29
32
|
ANIMATION_OUT: "unmountSuspended",
|
|
@@ -38,38 +41,41 @@ const usePresence = (options) => {
|
|
|
38
41
|
});
|
|
39
42
|
useEffect(() => {
|
|
40
43
|
const currentAnimationName = getAnimationName(stylesRef.current);
|
|
41
|
-
|
|
44
|
+
prevNodeStateRef.current.prevAnimationName = state === "mounted" ? currentAnimationName : "none";
|
|
42
45
|
}, [state]);
|
|
43
46
|
useLayoutEffect(() => {
|
|
44
47
|
const styles = stylesRef.current;
|
|
45
|
-
const wasPresent =
|
|
46
|
-
if (!(wasPresent !==
|
|
47
|
-
const prevAnimationName =
|
|
48
|
+
const wasPresent = prevNodeStateRef.current.prevPresent;
|
|
49
|
+
if (!(wasPresent !== presentProp)) return;
|
|
50
|
+
const prevAnimationName = prevNodeStateRef.current.prevAnimationName;
|
|
48
51
|
const currentAnimationName = getAnimationName(styles);
|
|
49
52
|
switch (true) {
|
|
50
|
-
case
|
|
53
|
+
case presentProp:
|
|
51
54
|
send("MOUNT");
|
|
55
|
+
if (variant === "transition") requestAnimationFrame(() => toggleHasTransitioned(true));
|
|
52
56
|
break;
|
|
53
|
-
case Boolean(node):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
send("ANIMATION_OUT");
|
|
57
|
+
case Boolean(node) && variant === "animation": {
|
|
58
|
+
/**
|
|
59
|
+
* When `present` changes to `false`, we check changes to animation-name to
|
|
60
|
+
* determine whether an animation has started. We chose this approach (reading
|
|
61
|
+
* computed styles) because there is no `animationrun` event (like the `transitionrun` event) and `animationstart`
|
|
62
|
+
* fires after `animation-delay` has expired which would be too late.
|
|
63
|
+
*/
|
|
64
|
+
const isAnimationStarted = currentAnimationName !== "none" && styles?.display !== "none" && prevAnimationName !== currentAnimationName;
|
|
65
|
+
send(wasPresent && isAnimationStarted ? "ANIMATION_OUT" : "UNMOUNT");
|
|
63
66
|
break;
|
|
67
|
+
}
|
|
64
68
|
default:
|
|
65
69
|
send("UNMOUNT");
|
|
66
70
|
break;
|
|
67
71
|
}
|
|
68
|
-
|
|
72
|
+
prevNodeStateRef.current.prevPresent = presentProp;
|
|
69
73
|
}, [
|
|
70
|
-
|
|
74
|
+
presentProp,
|
|
71
75
|
node,
|
|
72
|
-
send
|
|
76
|
+
send,
|
|
77
|
+
variant,
|
|
78
|
+
toggleHasTransitioned
|
|
73
79
|
]);
|
|
74
80
|
useLayoutEffect(() => {
|
|
75
81
|
if (!node) {
|
|
@@ -78,6 +84,10 @@ const usePresence = (options) => {
|
|
|
78
84
|
}
|
|
79
85
|
let timeoutId;
|
|
80
86
|
const ownerWindow = node.ownerDocument.defaultView ?? globalThis;
|
|
87
|
+
const handleAnimationStart = (event) => {
|
|
88
|
+
if (!(event.target === node)) return;
|
|
89
|
+
prevNodeStateRef.current.prevAnimationName = getAnimationName(stylesRef.current);
|
|
90
|
+
};
|
|
81
91
|
/**
|
|
82
92
|
* @description Triggering an ANIMATION_OUT during an ANIMATION_IN will fire an `animationcancel`
|
|
83
93
|
* event for ANIMATION_IN after we have entered `unmountSuspended` state. So, we
|
|
@@ -87,7 +97,7 @@ const usePresence = (options) => {
|
|
|
87
97
|
const isCurrentAnimation = getAnimationName(stylesRef.current).includes(CSS.escape(event.animationName));
|
|
88
98
|
if (!(event.target === node && isCurrentAnimation)) return;
|
|
89
99
|
send("ANIMATION_END");
|
|
90
|
-
if (!
|
|
100
|
+
if (!prevNodeStateRef.current.prevPresent) {
|
|
91
101
|
const currentFillMode = node.style.animationFillMode;
|
|
92
102
|
node.style.animationFillMode = "forwards";
|
|
93
103
|
timeoutId = ownerWindow.setTimeout(() => {
|
|
@@ -95,17 +105,18 @@ const usePresence = (options) => {
|
|
|
95
105
|
});
|
|
96
106
|
}
|
|
97
107
|
};
|
|
108
|
+
const handleTransitionRun = (event) => {
|
|
109
|
+
if (!(event.target === node)) return;
|
|
110
|
+
send("ANIMATION_OUT");
|
|
111
|
+
};
|
|
98
112
|
const handleTransitionEnd = (event) => {
|
|
99
|
-
if (!(event.target === node && !
|
|
113
|
+
if (!(event.target === node && !prevNodeStateRef.current.prevPresent)) return;
|
|
100
114
|
send("ANIMATION_END");
|
|
101
115
|
};
|
|
102
|
-
const handleAnimationStart = (event) => {
|
|
103
|
-
if (!(event.target === node)) return;
|
|
104
|
-
prevAnimationNameRef.current = getAnimationName(stylesRef.current);
|
|
105
|
-
};
|
|
106
116
|
const onAnimationStartCleanup = on("animationstart", node, handleAnimationStart);
|
|
107
117
|
const onAnimationEndCleanup = on("animationend", node, handleAnimationEnd);
|
|
108
118
|
const onAnimationCancelCleanup = on("animationcancel", node, handleAnimationEnd);
|
|
119
|
+
const onTransitionRunCleanup = on("transitionrun", node, handleTransitionRun);
|
|
109
120
|
const onTransitionEndCleanup = on("transitionend", node, handleTransitionEnd);
|
|
110
121
|
const onTransitionCancelCleanup = on("transitioncancel", node, handleTransitionEnd);
|
|
111
122
|
return () => {
|
|
@@ -113,44 +124,55 @@ const usePresence = (options) => {
|
|
|
113
124
|
onAnimationStartCleanup();
|
|
114
125
|
onAnimationEndCleanup();
|
|
115
126
|
onAnimationCancelCleanup();
|
|
127
|
+
onTransitionRunCleanup();
|
|
116
128
|
onTransitionEndCleanup();
|
|
117
129
|
onTransitionCancelCleanup();
|
|
118
130
|
};
|
|
119
131
|
}, [node, send]);
|
|
120
132
|
useEffect(() => {
|
|
121
|
-
if (
|
|
122
|
-
|
|
133
|
+
if (state === "unmounted" && !presentProp) {
|
|
134
|
+
toggleHasTransitioned(false);
|
|
135
|
+
stableOnExitComplete();
|
|
136
|
+
}
|
|
123
137
|
}, [
|
|
124
138
|
state,
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
presentProp,
|
|
140
|
+
stableOnExitComplete,
|
|
141
|
+
toggleHasTransitioned
|
|
127
142
|
]);
|
|
128
|
-
const isPresent = ["mounted", "unmountSuspended"].includes(state);
|
|
129
143
|
const ref = useCallbackRef((refNode) => {
|
|
130
|
-
refNode && (stylesRef.current = getComputedStyle(refNode));
|
|
131
144
|
setNode(refNode);
|
|
145
|
+
if (refNode) stylesRef.current = getComputedStyle(refNode);
|
|
132
146
|
});
|
|
147
|
+
const isPresent = ["mounted", "unmountSuspended"].includes(state);
|
|
133
148
|
return {
|
|
134
149
|
isPresent,
|
|
135
|
-
|
|
150
|
+
isPresentOrIsTransitionComplete: isPresent || hasTransitioned,
|
|
151
|
+
ref,
|
|
152
|
+
shouldStartTransition: presentProp && hasTransitioned
|
|
136
153
|
};
|
|
137
154
|
};
|
|
138
155
|
|
|
139
156
|
//#endregion
|
|
140
157
|
//#region src/components/common/presence/presence.tsx
|
|
141
158
|
function Presence(props) {
|
|
142
|
-
const { children, forceMount = false, onExitComplete, present } = props;
|
|
143
|
-
const
|
|
159
|
+
const { children, forceMount = false, onExitComplete, present, variant } = props;
|
|
160
|
+
const { isPresent, isPresentOrIsTransitionComplete, ref: presenceRef, shouldStartTransition } = usePresence({
|
|
144
161
|
onExitComplete,
|
|
145
|
-
present
|
|
162
|
+
present,
|
|
163
|
+
variant
|
|
146
164
|
});
|
|
147
|
-
const resolvedChild = isFunction(children) ? children({
|
|
165
|
+
const resolvedChild = isFunction(children) ? children({
|
|
166
|
+
isPresent,
|
|
167
|
+
isPresentOrIsTransitionComplete,
|
|
168
|
+
shouldStartTransition
|
|
169
|
+
}) : Children.only(children);
|
|
148
170
|
const childRef = resolvedChild?.props.ref ?? resolvedChild.ref;
|
|
149
|
-
const
|
|
150
|
-
if (!(forceMount ||
|
|
151
|
-
return resolvedChild && cloneElement(resolvedChild, { ref });
|
|
171
|
+
const combinedRefs = useComposeRefs(presenceRef, childRef);
|
|
172
|
+
if (!(forceMount || (variant === "transition" ? isPresentOrIsTransitionComplete : isPresent))) return null;
|
|
173
|
+
return resolvedChild && cloneElement(resolvedChild, { ref: combinedRefs });
|
|
152
174
|
}
|
|
153
175
|
|
|
154
176
|
//#endregion
|
|
155
177
|
export { Presence };
|
|
156
|
-
//# sourceMappingURL=presence-
|
|
178
|
+
//# sourceMappingURL=presence-CzmCEhXS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presence-CzmCEhXS.js","names":["timeoutId: number"],"sources":["../../src/components/common/presence/use-presence.ts","../../src/components/common/presence/presence.tsx"],"sourcesContent":["import { on } from \"@zayne-labs/toolkit-core\";\nimport { useCallbackRef, useToggle } from \"@zayne-labs/toolkit-react\";\nimport { useEffect, useLayoutEffect, useReducer, useRef, useState } from \"react\";\n\ntype StateMachineConfig<TState extends string, TEvent extends string> = {\n\tinitial: TState;\n\tstates: Record<TState, Partial<Record<TEvent, TState>>>;\n};\n\nconst useStateMachine = <TState extends string, TEvent extends string>(\n\tconfig: StateMachineConfig<TState, TEvent>\n) => {\n\tconst reducer = (prevState: TState, event: TEvent): TState => {\n\t\tconst newState = config.states[prevState][event] ?? prevState;\n\n\t\treturn newState;\n\t};\n\n\treturn useReducer(reducer, config.initial);\n};\n\nconst getAnimationName = (styles: CSSStyleDeclaration | null) => styles?.animationName ?? \"none\";\n\nexport type UsePresenceOptions = {\n\tonExitComplete?: () => void;\n\tpresent: boolean;\n\t/**\n\t * @default \"animation\"\n\t */\n\tvariant?: \"animation\" | \"transition\";\n};\n\n/**\n * React hook that provides the ability to animate the mount/unmount of a component.\n * @see https://github.com/radix-ui/primitives/blob/main/packages/react/presence/src/presence.tsx\n */\n\nconst usePresence = (options: UsePresenceOptions) => {\n\tconst { onExitComplete, present: presentProp, variant = \"animation\" } = options;\n\n\tconst stableOnExitComplete = useCallbackRef(onExitComplete);\n\n\tconst [node, setNode] = useState<HTMLElement | null>(null);\n\n\tconst [hasTransitioned, toggleHasTransitioned] = useToggle(false);\n\n\tconst stylesRef = useRef<CSSStyleDeclaration | null>(null);\n\n\tconst prevNodeStateRef = useRef<{\n\t\tprevAnimationName: string;\n\t\tprevPresent: boolean;\n\t}>({\n\t\tprevAnimationName: \"none\",\n\t\tprevPresent: presentProp,\n\t});\n\n\tconst initialState = presentProp ? \"mounted\" : \"unmounted\";\n\n\tconst [state, send] = useStateMachine({\n\t\tinitial: initialState,\n\t\tstates: {\n\t\t\tmounted: {\n\t\t\t\tANIMATION_OUT: \"unmountSuspended\",\n\t\t\t\tUNMOUNT: \"unmounted\",\n\t\t\t},\n\t\t\tunmounted: {\n\t\t\t\tMOUNT: \"mounted\",\n\t\t\t},\n\t\t\tunmountSuspended: {\n\t\t\t\tANIMATION_END: \"unmounted\",\n\t\t\t\tMOUNT: \"mounted\",\n\t\t\t},\n\t\t},\n\t});\n\n\tuseEffect(() => {\n\t\tconst currentAnimationName = getAnimationName(stylesRef.current);\n\n\t\tprevNodeStateRef.current.prevAnimationName = state === \"mounted\" ? currentAnimationName : \"none\";\n\t}, [state]);\n\n\tuseLayoutEffect(() => {\n\t\tconst styles = stylesRef.current;\n\t\tconst wasPresent = prevNodeStateRef.current.prevPresent;\n\t\tconst hasPresentChanged = wasPresent !== presentProp;\n\n\t\tif (!hasPresentChanged) return;\n\n\t\tconst prevAnimationName = prevNodeStateRef.current.prevAnimationName;\n\t\tconst currentAnimationName = getAnimationName(styles);\n\n\t\tswitch (true) {\n\t\t\tcase presentProp: {\n\t\t\t\tsend(\"MOUNT\");\n\n\t\t\t\tif (variant === \"transition\") {\n\t\t\t\t\trequestAnimationFrame(() => toggleHasTransitioned(true));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase Boolean(node) && variant === \"animation\": {\n\t\t\t\tconst hasAnimation = currentAnimationName !== \"none\" && styles?.display !== \"none\";\n\n\t\t\t\t/**\n\t\t\t\t * When `present` changes to `false`, we check changes to animation-name to\n\t\t\t\t * determine whether an animation has started. We chose this approach (reading\n\t\t\t\t * computed styles) because there is no `animationrun` event (like the `transitionrun` event) and `animationstart`\n\t\t\t\t * fires after `animation-delay` has expired which would be too late.\n\t\t\t\t */\n\n\t\t\t\tconst isAnimationStarted = hasAnimation && prevAnimationName !== currentAnimationName;\n\n\t\t\t\tconst isAnimatingOut = wasPresent && isAnimationStarted;\n\n\t\t\t\tsend(isAnimatingOut ? \"ANIMATION_OUT\" : \"UNMOUNT\");\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tsend(\"UNMOUNT\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprevNodeStateRef.current.prevPresent = presentProp;\n\t}, [presentProp, node, send, variant, toggleHasTransitioned]);\n\n\tuseLayoutEffect(() => {\n\t\tif (!node) {\n\t\t\t// Transition to the unmounted state if the node is removed prematurely.\n\t\t\t// We avoid doing so during cleanup as the node may change but still exist.\n\t\t\tsend(\"ANIMATION_END\");\n\t\t\treturn;\n\t\t}\n\n\t\tlet timeoutId: number;\n\n\t\tconst ownerWindow = node.ownerDocument.defaultView ?? globalThis;\n\n\t\tconst handleAnimationStart = (event: AnimationEvent) => {\n\t\t\tconst isTargetAnimatingNode = event.target === node;\n\n\t\t\tif (!isTargetAnimatingNode) return;\n\n\t\t\tprevNodeStateRef.current.prevAnimationName = getAnimationName(stylesRef.current);\n\t\t};\n\n\t\t/**\n\t\t * @description Triggering an ANIMATION_OUT during an ANIMATION_IN will fire an `animationcancel`\n\t\t * event for ANIMATION_IN after we have entered `unmountSuspended` state. So, we\n\t\t * make sure we only trigger ANIMATION_END for the currently active animation.\n\t\t */\n\t\tconst handleAnimationEnd = (event: AnimationEvent) => {\n\t\t\tconst currentAnimationName = getAnimationName(stylesRef.current);\n\n\t\t\t// The event.animationName is unescaped for CSS syntax, so we need to escape it to compare with the animationName computed from the style.\n\t\t\tconst isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName));\n\n\t\t\tconst isTargetAnimatingNode = event.target === node && isCurrentAnimation;\n\n\t\t\tif (!isTargetAnimatingNode) return;\n\n\t\t\t// With React 18 concurrency this update is applied a frame after the\n\t\t\t// animation ends, creating a flash of visible content. By setting the\n\t\t\t// animation fill mode to \"forwards\", we force the node to keep the\n\t\t\t// styles of the last keyframe, removing the flash.\n\n\t\t\t// Previously we flushed the update via ReactDom.flushSync, but with\n\t\t\t// exit animations this resulted in the node being removed from the\n\t\t\t// DOM before the synthetic animationEnd event was dispatched, meaning\n\t\t\t// user-provided event handlers would not be called.\n\t\t\t// https://github.com/radix-ui/primitives/pull/1849\n\t\t\tsend(\"ANIMATION_END\");\n\n\t\t\tif (!prevNodeStateRef.current.prevPresent) {\n\t\t\t\tconst currentFillMode = node.style.animationFillMode;\n\t\t\t\tnode.style.animationFillMode = \"forwards\";\n\n\t\t\t\t// Reset the style after the node had time to unmount (for cases\n\t\t\t\t// where the component chooses not to unmount). Doing this any\n\t\t\t\t// sooner than `setTimeout` (e.g. with `requestAnimationFrame`)\n\t\t\t\t// still causes a flash.\n\t\t\t\ttimeoutId = ownerWindow.setTimeout(() => {\n\t\t\t\t\tif (node.style.animationFillMode === \"forwards\") {\n\t\t\t\t\t\tnode.style.animationFillMode = currentFillMode;\n\t\t\t\t\t}\n\t\t\t\t}) as never;\n\t\t\t}\n\t\t};\n\n\t\tconst handleTransitionRun = (event: TransitionEvent) => {\n\t\t\tconst isTargetTransitioningNode = event.target === node;\n\n\t\t\tif (!isTargetTransitioningNode) return;\n\n\t\t\tsend(\"ANIMATION_OUT\");\n\t\t};\n\n\t\tconst handleTransitionEnd = (event: TransitionEvent) => {\n\t\t\tconst isTargetTransitioningNode = event.target === node && !prevNodeStateRef.current.prevPresent;\n\n\t\t\tif (!isTargetTransitioningNode) return;\n\n\t\t\tsend(\"ANIMATION_END\");\n\t\t};\n\n\t\tconst onAnimationStartCleanup = on(\"animationstart\", node, handleAnimationStart);\n\t\tconst onAnimationEndCleanup = on(\"animationend\", node, handleAnimationEnd);\n\t\tconst onAnimationCancelCleanup = on(\"animationcancel\", node, handleAnimationEnd);\n\n\t\tconst onTransitionRunCleanup = on(\"transitionrun\", node, handleTransitionRun);\n\t\tconst onTransitionEndCleanup = on(\"transitionend\", node, handleTransitionEnd);\n\t\tconst onTransitionCancelCleanup = on(\"transitioncancel\", node, handleTransitionEnd);\n\n\t\treturn () => {\n\t\t\townerWindow.clearTimeout(timeoutId);\n\t\t\tonAnimationStartCleanup();\n\t\t\tonAnimationEndCleanup();\n\t\t\tonAnimationCancelCleanup();\n\n\t\t\tonTransitionRunCleanup();\n\t\t\tonTransitionEndCleanup();\n\t\t\tonTransitionCancelCleanup();\n\t\t};\n\t}, [node, send]);\n\n\tuseEffect(() => {\n\t\tconst isExitCompleted = state === \"unmounted\" && !presentProp;\n\n\t\tif (isExitCompleted) {\n\t\t\ttoggleHasTransitioned(false);\n\t\t\tstableOnExitComplete();\n\t\t}\n\t}, [state, presentProp, stableOnExitComplete, toggleHasTransitioned]);\n\n\tconst ref = useCallbackRef((refNode: HTMLElement | null) => {\n\t\tsetNode(refNode);\n\n\t\tif (refNode) {\n\t\t\tstylesRef.current = getComputedStyle(refNode);\n\t\t}\n\t});\n\n\tconst MOUNTED_STATES = [\"mounted\", \"unmountSuspended\"] satisfies Array<typeof state>;\n\tconst isPresent = MOUNTED_STATES.includes(state);\n\n\treturn {\n\t\tisPresent,\n\t\tisPresentOrIsTransitionComplete: isPresent || hasTransitioned,\n\t\tref,\n\t\tshouldStartTransition: presentProp && hasTransitioned,\n\t};\n};\n\nexport { usePresence };\n","\"use client\";\n\nimport { useComposeRefs } from \"@zayne-labs/toolkit-react\";\nimport { isFunction, type UnknownObject } from \"@zayne-labs/toolkit-type-helpers\";\nimport * as React from \"react\";\nimport { Children, cloneElement } from \"react\";\nimport { type UsePresenceOptions, usePresence } from \"./use-presence\";\n\ntype RefProp = { ref?: React.Ref<HTMLElement> };\n\ntype PresenceProps = UsePresenceOptions & {\n\tchildren?:\n\t\t| React.ReactElement<RefProp>\n\t\t| ((props: Omit<ReturnType<typeof usePresence>, \"ref\">) => React.ReactElement<RefProp>);\n\tforceMount?: boolean;\n};\n\nfunction Presence(props: PresenceProps) {\n\tconst { children, forceMount = false, onExitComplete, present, variant } = props;\n\n\tconst {\n\t\tisPresent,\n\t\tisPresentOrIsTransitionComplete,\n\t\tref: presenceRef,\n\t\tshouldStartTransition,\n\t} = usePresence({ onExitComplete, present, variant });\n\n\tconst resolvedChild =\n\t\tisFunction(children) ?\n\t\t\tchildren({ isPresent, isPresentOrIsTransitionComplete, shouldStartTransition })\n\t\t:\tChildren.only(children);\n\n\tconst childRef = (resolvedChild?.props.ref\n\t\t?? (resolvedChild as unknown as UnknownObject).ref) as React.Ref<HTMLElement>;\n\n\tconst combinedRefs = useComposeRefs(presenceRef, childRef);\n\n\tconst shouldRender =\n\t\tforceMount || (variant === \"transition\" ? isPresentOrIsTransitionComplete : isPresent);\n\n\tif (!shouldRender) {\n\t\treturn null;\n\t}\n\n\treturn resolvedChild && cloneElement(resolvedChild, { ref: combinedRefs });\n}\n\nexport { Presence };\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PolymorphicPropsStrict } from "@zayne-labs/toolkit-react/utils";
|
|
2
2
|
import { UnionDiscriminator } from "@zayne-labs/toolkit-type-helpers";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
|
-
import * as
|
|
4
|
+
import * as react_jsx_runtime8 from "react/jsx-runtime";
|
|
5
5
|
import { StoreApi } from "@zayne-labs/toolkit-core";
|
|
6
6
|
|
|
7
7
|
//#region src/components/ui/carousel/types.d.ts
|
|
@@ -79,14 +79,14 @@ type OtherCarouselProps = {
|
|
|
79
79
|
};
|
|
80
80
|
//#endregion
|
|
81
81
|
//#region src/components/ui/carousel/carousel.d.ts
|
|
82
|
-
declare function CarouselRoot<TImages extends ImagesType, TElement extends React$1.ElementType = "div">(props: PolymorphicPropsStrict<TElement, CarouselRootProps<TImages>>):
|
|
83
|
-
declare function CarouselButton(props: CarouselButtonsProps):
|
|
84
|
-
declare function CarouselControls(props: CarouselControlProps):
|
|
85
|
-
declare function CarouselItemList<TArray extends unknown[]>(props: CarouselWrapperProps<TArray[number]>):
|
|
86
|
-
declare function CarouselItem(props: OtherCarouselProps):
|
|
87
|
-
declare function CarouselCaption<TElement extends React$1.ElementType = "div">(props: PolymorphicPropsStrict<TElement, OtherCarouselProps>):
|
|
88
|
-
declare function CarouselIndicatorList<TArray extends unknown[]>(props: CarouselWrapperProps<TArray[number]>):
|
|
89
|
-
declare function CarouselIndicator(props: CarouselIndicatorProps):
|
|
82
|
+
declare function CarouselRoot<TImages extends ImagesType, TElement extends React$1.ElementType = "div">(props: PolymorphicPropsStrict<TElement, CarouselRootProps<TImages>>): react_jsx_runtime8.JSX.Element;
|
|
83
|
+
declare function CarouselButton(props: CarouselButtonsProps): react_jsx_runtime8.JSX.Element;
|
|
84
|
+
declare function CarouselControls(props: CarouselControlProps): react_jsx_runtime8.JSX.Element;
|
|
85
|
+
declare function CarouselItemList<TArray extends unknown[]>(props: CarouselWrapperProps<TArray[number]>): react_jsx_runtime8.JSX.Element;
|
|
86
|
+
declare function CarouselItem(props: OtherCarouselProps): react_jsx_runtime8.JSX.Element;
|
|
87
|
+
declare function CarouselCaption<TElement extends React$1.ElementType = "div">(props: PolymorphicPropsStrict<TElement, OtherCarouselProps>): react_jsx_runtime8.JSX.Element;
|
|
88
|
+
declare function CarouselIndicatorList<TArray extends unknown[]>(props: CarouselWrapperProps<TArray[number]>): react_jsx_runtime8.JSX.Element;
|
|
89
|
+
declare function CarouselIndicator(props: CarouselIndicatorProps): react_jsx_runtime8.JSX.Element;
|
|
90
90
|
declare namespace carousel_parts_d_exports {
|
|
91
91
|
export { CarouselButton as Button, CarouselCaption as Caption, CarouselControls as Controls, CarouselIndicator as Indicator, CarouselIndicatorList as IndicatorList, CarouselItem as Item, CarouselItemList as ItemList, CarouselRoot as Root };
|
|
92
92
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cnMerge } from "../../cn-DdD3uYxA.js";
|
|
2
2
|
import { composeRefs, mergeTwoProps } from "@zayne-labs/toolkit-react/utils";
|
|
3
3
|
import { useCallback, useMemo, useRef } from "react";
|
|
4
|
-
import { useCallbackRef } from "@zayne-labs/toolkit-react";
|
|
5
|
-
import { checkIsDeviceMobile,
|
|
4
|
+
import { useCallbackRef, useLazyRef } from "@zayne-labs/toolkit-react";
|
|
5
|
+
import { checkIsDeviceMobile, on } from "@zayne-labs/toolkit-core";
|
|
6
6
|
|
|
7
7
|
//#region src/components/ui/drag-scroll/utils.ts
|
|
8
8
|
const updateCursor = (element) => {
|
|
@@ -36,6 +36,11 @@ const useDragScroll = (props) => {
|
|
|
36
36
|
x: 0,
|
|
37
37
|
y: 0
|
|
38
38
|
});
|
|
39
|
+
const abortControllersRef = useLazyRef(() => ({
|
|
40
|
+
mouseLeave: new AbortController(),
|
|
41
|
+
mouseMove: new AbortController(),
|
|
42
|
+
mouseUp: new AbortController()
|
|
43
|
+
}));
|
|
39
44
|
const handleMouseMove = useCallbackRef((event) => {
|
|
40
45
|
if (!dragContainerRef.current) return;
|
|
41
46
|
if (orientation === "horizontal" || orientation === "both") {
|
|
@@ -49,10 +54,10 @@ const useDragScroll = (props) => {
|
|
|
49
54
|
});
|
|
50
55
|
const handleMouseUpOrLeave = useCallbackRef(() => {
|
|
51
56
|
if (!dragContainerRef.current) return;
|
|
52
|
-
off("mousemove", dragContainerRef.current, handleMouseMove);
|
|
53
|
-
off("mouseup", dragContainerRef.current, handleMouseUpOrLeave);
|
|
54
|
-
off("mouseleave", dragContainerRef.current, handleMouseUpOrLeave);
|
|
55
57
|
resetCursor(dragContainerRef.current);
|
|
58
|
+
abortControllersRef.current.mouseMove.abort();
|
|
59
|
+
abortControllersRef.current.mouseUp.abort();
|
|
60
|
+
abortControllersRef.current.mouseLeave.abort();
|
|
56
61
|
});
|
|
57
62
|
const handleMouseDown = useCallbackRef((event) => {
|
|
58
63
|
if (usage === "mobileAndTabletOnly" && window.innerWidth >= 768) return;
|
|
@@ -67,9 +72,9 @@ const useDragScroll = (props) => {
|
|
|
67
72
|
positionRef.current.top = dragContainerRef.current.scrollTop;
|
|
68
73
|
}
|
|
69
74
|
updateCursor(dragContainerRef.current);
|
|
70
|
-
on("mousemove", dragContainerRef.current, handleMouseMove);
|
|
71
|
-
on("mouseup", dragContainerRef.current, handleMouseUpOrLeave);
|
|
72
|
-
on("mouseleave", dragContainerRef.current, handleMouseUpOrLeave);
|
|
75
|
+
on("mousemove", dragContainerRef.current, handleMouseMove, { signal: abortControllersRef.current.mouseMove.signal });
|
|
76
|
+
on("mouseup", dragContainerRef.current, handleMouseUpOrLeave, { signal: abortControllersRef.current.mouseUp.signal });
|
|
77
|
+
on("mouseleave", dragContainerRef.current, handleMouseUpOrLeave, { signal: abortControllersRef.current.mouseLeave.signal });
|
|
73
78
|
});
|
|
74
79
|
const refCallBack = useCallbackRef((node) => {
|
|
75
80
|
dragContainerRef.current = node;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["refCallBack: RefCallback<TElement>","getRootProps: DragScrollResult<TElement, TItemElement>[\"getRootProps\"]","getItemProps: DragScrollResult<TElement, TItemElement>[\"getItemProps\"]"],"sources":["../../../../src/components/ui/drag-scroll/utils.ts","../../../../src/components/ui/drag-scroll/use-drag-scroll.ts"],"sourcesContent":["import { checkIsDeviceMobile } from \"@zayne-labs/toolkit-core\";\n\n/* eslint-disable no-param-reassign -- Mutation is needed here since it's an element */\nexport const updateCursor = <TElement extends HTMLElement>(element: TElement) => {\n\telement.style.cursor = \"grabbing\";\n\telement.style.userSelect = \"none\";\n};\n\nexport const onScrollSnap = <TElement extends HTMLElement>(\n\taction: \"remove\" | \"reset\",\n\telement: TElement\n) => {\n\tif (action === \"remove\") {\n\t\telement.style.scrollSnapType = \"none\";\n\t\treturn;\n\t}\n\n\telement.style.scrollSnapType = \"\";\n};\n\nexport const resetCursor = <TElement extends HTMLElement>(element: TElement) => {\n\telement.style.cursor = \"\";\n\telement.style.userSelect = \"\";\n};\n/* eslint-enable no-param-reassign -- Mutation is needed here since it's an element */\n\nexport const handleScrollSnap = (dragContainer: HTMLElement) => {\n\tconst isMobile = checkIsDeviceMobile();\n\n\tif (!isMobile) {\n\t\tonScrollSnap(\"remove\", dragContainer);\n\t} else {\n\t\tonScrollSnap(\"reset\", dragContainer);\n\t}\n};\n","import { off, on } from \"@zayne-labs/toolkit-core\";\nimport { useCallbackRef } from \"@zayne-labs/toolkit-react\";\nimport { composeRefs, type InferProps, mergeTwoProps } from \"@zayne-labs/toolkit-react/utils\";\nimport { type RefCallback, useCallback, useMemo, useRef } from \"react\";\nimport { cnMerge } from \"@/lib/utils/cn\";\nimport { handleScrollSnap, resetCursor, updateCursor } from \"./utils\";\n\ntype ItemProps<TItemElement extends HTMLElement> = Omit<InferProps<TItemElement>, \"children\">;\n\ntype RootProps<TElement extends HTMLElement> = Omit<InferProps<TElement>, \"children\">;\n\ntype DragScrollProps<TElement extends HTMLElement, TItemElement extends HTMLElement> = {\n\tclassNames?: { base?: string; item?: string };\n\textraItemProps?: ItemProps<TItemElement>;\n\textraRootProps?: InferProps<TElement>;\n\torientation?: \"both\" | \"horizontal\" | \"vertical\";\n\tusage?: \"allScreens\" | \"desktopOnly\" | \"mobileAndTabletOnly\";\n};\n\ntype DragScrollResult<TElement extends HTMLElement, TItemElement extends HTMLElement> = {\n\tgetItemProps: (itemProps?: ItemProps<TItemElement>) => ItemProps<TItemElement>;\n\tgetRootProps: (rootProps?: RootProps<TElement>) => RootProps<TElement>;\n};\n\nconst useDragScroll = <TElement extends HTMLElement, TItemElement extends HTMLElement = HTMLElement>(\n\tprops?: DragScrollProps<TElement, TItemElement>\n): DragScrollResult<TElement, TItemElement> => {\n\tconst {\n\t\tclassNames,\n\t\textraItemProps,\n\t\textraRootProps,\n\t\torientation = \"horizontal\",\n\t\tusage = \"allScreens\",\n\t} = props ?? {};\n\n\tconst dragContainerRef = useRef<TElement>(null);\n\n\tconst positionRef = useRef({ left: 0, top: 0, x: 0, y: 0 });\n\n\tconst handleMouseMove = useCallbackRef((event: MouseEvent) => {\n\t\tif (!dragContainerRef.current) return;\n\n\t\tif (orientation === \"horizontal\" || orientation === \"both\") {\n\t\t\t// == calculate the current change in the horizontal scroll position based on the difference between the previous mouse position and the new mouse position\n\t\t\tconst dx = event.clientX - positionRef.current.x;\n\n\t\t\t// == Assign the scrollLeft of the container to the difference between its previous horizontal scroll position and the change in the mouse position\n\t\t\tdragContainerRef.current.scrollLeft = positionRef.current.left - dx;\n\t\t}\n\n\t\tif (orientation === \"vertical\" || orientation === \"both\") {\n\t\t\t// == calculate the current change in the vertical scroll position based on the difference between the previous mouse position and the new mouse position\n\t\t\tconst dy = event.clientY - positionRef.current.y;\n\n\t\t\t// == Assign the scrollTop of the container to the difference between its previous vertical scroll position and the change in the mouse position\n\t\t\tdragContainerRef.current.scrollTop = positionRef.current.top - dy;\n\t\t}\n\t});\n\n\tconst handleMouseUpOrLeave = useCallbackRef(() => {\n\t\tif (!dragContainerRef.current) return;\n\n\t\toff(\"mousemove\", dragContainerRef.current, handleMouseMove);\n\t\toff(\"mouseup\", dragContainerRef.current, handleMouseUpOrLeave);\n\t\toff(\"mouseleave\", dragContainerRef.current, handleMouseUpOrLeave);\n\n\t\tresetCursor(dragContainerRef.current);\n\t});\n\n\tconst handleMouseDown = useCallbackRef((event: MouseEvent) => {\n\t\tif (usage === \"mobileAndTabletOnly\" && window.innerWidth >= 768) return;\n\t\tif (usage === \"desktopOnly\" && window.innerWidth < 768) return;\n\n\t\tif (!dragContainerRef.current) return;\n\n\t\t// == Update all initial position properties stored in the positionRef\n\t\tif (orientation === \"horizontal\" || orientation === \"both\") {\n\t\t\tpositionRef.current.x = event.clientX;\n\t\t\tpositionRef.current.left = dragContainerRef.current.scrollLeft;\n\t\t}\n\n\t\tif (orientation === \"vertical\" || orientation === \"both\") {\n\t\t\tpositionRef.current.y = event.clientY;\n\t\t\tpositionRef.current.top = dragContainerRef.current.scrollTop;\n\t\t}\n\n\t\tupdateCursor(dragContainerRef.current);\n\n\t\ton(\"mousemove\", dragContainerRef.current, handleMouseMove);\n\t\ton(\"mouseup\", dragContainerRef.current, handleMouseUpOrLeave);\n\t\ton(\"mouseleave\", dragContainerRef.current, handleMouseUpOrLeave);\n\t});\n\n\tconst refCallBack: RefCallback<TElement> = useCallbackRef((node) => {\n\t\tdragContainerRef.current = node;\n\n\t\tnode && handleScrollSnap(node);\n\n\t\tconst cleanup = on(\"mousedown\", dragContainerRef.current, handleMouseDown);\n\n\t\treturn cleanup;\n\t});\n\n\tconst getRootProps: DragScrollResult<TElement, TItemElement>[\"getRootProps\"] = useCallback(\n\t\t(rootProps) => {\n\t\t\tconst mergedRootProps = mergeTwoProps(extraRootProps, rootProps);\n\n\t\t\treturn {\n\t\t\t\t...mergedRootProps,\n\t\t\t\tclassName: cnMerge(\n\t\t\t\t\t`scrollbar-hidden flex w-full cursor-grab snap-x snap-mandatory overflow-x-scroll\n\t\t\t\t\toverflow-y-hidden`,\n\t\t\t\t\torientation === \"horizontal\" && \"flex-row\",\n\t\t\t\t\torientation === \"vertical\" && \"flex-col\",\n\t\t\t\t\tusage === \"mobileAndTabletOnly\" && \"md:cursor-default md:flex-col\",\n\t\t\t\t\tusage === \"desktopOnly\" && \"max-md:cursor-default max-md:flex-col\",\n\t\t\t\t\tclassNames?.base,\n\t\t\t\t\tmergedRootProps.className\n\t\t\t\t),\n\t\t\t\t\"data-part\": \"root\",\n\t\t\t\t\"data-scope\": \"drag-scroll\",\n\t\t\t\t\"data-slot\": \"drag-scroll-root\",\n\t\t\t\tref: composeRefs(\n\t\t\t\t\trefCallBack,\n\t\t\t\t\t(mergedRootProps as { ref?: React.Ref<TElement> } | undefined)?.ref\n\t\t\t\t),\n\t\t\t};\n\t\t},\n\t\t[extraRootProps, classNames?.base, orientation, refCallBack, usage]\n\t);\n\n\tconst getItemProps: DragScrollResult<TElement, TItemElement>[\"getItemProps\"] = useCallback(\n\t\t(itemProps) => {\n\t\t\tconst mergedItemProps = mergeTwoProps(extraItemProps, itemProps);\n\n\t\t\treturn {\n\t\t\t\t...mergedItemProps,\n\t\t\t\tclassName: cnMerge(\"snap-center snap-always\", classNames?.item, mergedItemProps.className),\n\t\t\t\t\"data-part\": \"item\",\n\t\t\t\t\"data-scope\": \"drag-scroll\",\n\t\t\t\t\"data-slot\": \"drag-scroll-item\",\n\t\t\t};\n\t\t},\n\t\t[extraItemProps, classNames?.item]\n\t);\n\n\tconst result = useMemo(() => ({ getItemProps, getRootProps }), [getItemProps, getRootProps]);\n\n\treturn result;\n};\n\nexport { useDragScroll };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["refCallBack: RefCallback<TElement>","getRootProps: DragScrollResult<TElement, TItemElement>[\"getRootProps\"]","getItemProps: DragScrollResult<TElement, TItemElement>[\"getItemProps\"]"],"sources":["../../../../src/components/ui/drag-scroll/utils.ts","../../../../src/components/ui/drag-scroll/use-drag-scroll.ts"],"sourcesContent":["import { checkIsDeviceMobile } from \"@zayne-labs/toolkit-core\";\n\n/* eslint-disable no-param-reassign -- Mutation is needed here since it's an element */\nexport const updateCursor = <TElement extends HTMLElement>(element: TElement) => {\n\telement.style.cursor = \"grabbing\";\n\telement.style.userSelect = \"none\";\n};\n\nexport const onScrollSnap = <TElement extends HTMLElement>(\n\taction: \"remove\" | \"reset\",\n\telement: TElement\n) => {\n\tif (action === \"remove\") {\n\t\telement.style.scrollSnapType = \"none\";\n\t\treturn;\n\t}\n\n\telement.style.scrollSnapType = \"\";\n};\n\nexport const resetCursor = <TElement extends HTMLElement>(element: TElement) => {\n\telement.style.cursor = \"\";\n\telement.style.userSelect = \"\";\n};\n/* eslint-enable no-param-reassign -- Mutation is needed here since it's an element */\n\nexport const handleScrollSnap = (dragContainer: HTMLElement) => {\n\tconst isMobile = checkIsDeviceMobile();\n\n\tif (!isMobile) {\n\t\tonScrollSnap(\"remove\", dragContainer);\n\t} else {\n\t\tonScrollSnap(\"reset\", dragContainer);\n\t}\n};\n","import { on } from \"@zayne-labs/toolkit-core\";\nimport { useCallbackRef, useLazyRef } from \"@zayne-labs/toolkit-react\";\nimport { composeRefs, type InferProps, mergeTwoProps } from \"@zayne-labs/toolkit-react/utils\";\nimport { type RefCallback, useCallback, useMemo, useRef } from \"react\";\nimport { cnMerge } from \"@/lib/utils/cn\";\nimport { handleScrollSnap, resetCursor, updateCursor } from \"./utils\";\n\ntype ItemProps<TItemElement extends HTMLElement> = Omit<InferProps<TItemElement>, \"children\">;\n\ntype RootProps<TElement extends HTMLElement> = Omit<InferProps<TElement>, \"children\">;\n\ntype DragScrollProps<TElement extends HTMLElement, TItemElement extends HTMLElement> = {\n\tclassNames?: { base?: string; item?: string };\n\textraItemProps?: ItemProps<TItemElement>;\n\textraRootProps?: InferProps<TElement>;\n\torientation?: \"both\" | \"horizontal\" | \"vertical\";\n\tusage?: \"allScreens\" | \"desktopOnly\" | \"mobileAndTabletOnly\";\n};\n\ntype DragScrollResult<TElement extends HTMLElement, TItemElement extends HTMLElement> = {\n\tgetItemProps: (itemProps?: ItemProps<TItemElement>) => ItemProps<TItemElement>;\n\tgetRootProps: (rootProps?: RootProps<TElement>) => RootProps<TElement>;\n};\n\nconst useDragScroll = <TElement extends HTMLElement, TItemElement extends HTMLElement = HTMLElement>(\n\tprops?: DragScrollProps<TElement, TItemElement>\n): DragScrollResult<TElement, TItemElement> => {\n\tconst {\n\t\tclassNames,\n\t\textraItemProps,\n\t\textraRootProps,\n\t\torientation = \"horizontal\",\n\t\tusage = \"allScreens\",\n\t} = props ?? {};\n\n\tconst dragContainerRef = useRef<TElement>(null);\n\n\tconst positionRef = useRef({ left: 0, top: 0, x: 0, y: 0 });\n\n\tconst abortControllersRef = useLazyRef(() => ({\n\t\tmouseLeave: new AbortController(),\n\t\tmouseMove: new AbortController(),\n\t\tmouseUp: new AbortController(),\n\t}));\n\n\tconst handleMouseMove = useCallbackRef((event: MouseEvent) => {\n\t\tif (!dragContainerRef.current) return;\n\n\t\tif (orientation === \"horizontal\" || orientation === \"both\") {\n\t\t\t// == calculate the current change in the horizontal scroll position based on the difference between the previous mouse position and the new mouse position\n\t\t\tconst dx = event.clientX - positionRef.current.x;\n\n\t\t\t// == Assign the scrollLeft of the container to the difference between its previous horizontal scroll position and the change in the mouse position\n\t\t\tdragContainerRef.current.scrollLeft = positionRef.current.left - dx;\n\t\t}\n\n\t\tif (orientation === \"vertical\" || orientation === \"both\") {\n\t\t\t// == calculate the current change in the vertical scroll position based on the difference between the previous mouse position and the new mouse position\n\t\t\tconst dy = event.clientY - positionRef.current.y;\n\n\t\t\t// == Assign the scrollTop of the container to the difference between its previous vertical scroll position and the change in the mouse position\n\t\t\tdragContainerRef.current.scrollTop = positionRef.current.top - dy;\n\t\t}\n\t});\n\n\tconst handleMouseUpOrLeave = useCallbackRef(() => {\n\t\tif (!dragContainerRef.current) return;\n\n\t\tresetCursor(dragContainerRef.current);\n\n\t\tabortControllersRef.current.mouseMove.abort();\n\t\tabortControllersRef.current.mouseUp.abort();\n\t\tabortControllersRef.current.mouseLeave.abort();\n\t});\n\n\tconst handleMouseDown = useCallbackRef((event: MouseEvent) => {\n\t\tif (usage === \"mobileAndTabletOnly\" && window.innerWidth >= 768) return;\n\t\tif (usage === \"desktopOnly\" && window.innerWidth < 768) return;\n\n\t\tif (!dragContainerRef.current) return;\n\n\t\t// == Update all initial position properties stored in the positionRef\n\t\tif (orientation === \"horizontal\" || orientation === \"both\") {\n\t\t\tpositionRef.current.x = event.clientX;\n\t\t\tpositionRef.current.left = dragContainerRef.current.scrollLeft;\n\t\t}\n\n\t\tif (orientation === \"vertical\" || orientation === \"both\") {\n\t\t\tpositionRef.current.y = event.clientY;\n\t\t\tpositionRef.current.top = dragContainerRef.current.scrollTop;\n\t\t}\n\n\t\tupdateCursor(dragContainerRef.current);\n\n\t\ton(\"mousemove\", dragContainerRef.current, handleMouseMove, {\n\t\t\tsignal: abortControllersRef.current.mouseMove.signal,\n\t\t});\n\t\ton(\"mouseup\", dragContainerRef.current, handleMouseUpOrLeave, {\n\t\t\tsignal: abortControllersRef.current.mouseUp.signal,\n\t\t});\n\t\ton(\"mouseleave\", dragContainerRef.current, handleMouseUpOrLeave, {\n\t\t\tsignal: abortControllersRef.current.mouseLeave.signal,\n\t\t});\n\t});\n\n\tconst refCallBack: RefCallback<TElement> = useCallbackRef((node) => {\n\t\tdragContainerRef.current = node;\n\n\t\tnode && handleScrollSnap(node);\n\n\t\tconst cleanup = on(\"mousedown\", dragContainerRef.current, handleMouseDown);\n\n\t\treturn cleanup;\n\t});\n\n\tconst getRootProps: DragScrollResult<TElement, TItemElement>[\"getRootProps\"] = useCallback(\n\t\t(rootProps) => {\n\t\t\tconst mergedRootProps = mergeTwoProps(extraRootProps, rootProps);\n\n\t\t\treturn {\n\t\t\t\t...mergedRootProps,\n\t\t\t\tclassName: cnMerge(\n\t\t\t\t\t`scrollbar-hidden flex w-full cursor-grab snap-x snap-mandatory overflow-x-scroll\n\t\t\t\t\toverflow-y-hidden`,\n\t\t\t\t\torientation === \"horizontal\" && \"flex-row\",\n\t\t\t\t\torientation === \"vertical\" && \"flex-col\",\n\t\t\t\t\tusage === \"mobileAndTabletOnly\" && \"md:cursor-default md:flex-col\",\n\t\t\t\t\tusage === \"desktopOnly\" && \"max-md:cursor-default max-md:flex-col\",\n\t\t\t\t\tclassNames?.base,\n\t\t\t\t\tmergedRootProps.className\n\t\t\t\t),\n\t\t\t\t\"data-part\": \"root\",\n\t\t\t\t\"data-scope\": \"drag-scroll\",\n\t\t\t\t\"data-slot\": \"drag-scroll-root\",\n\t\t\t\tref: composeRefs(\n\t\t\t\t\trefCallBack,\n\t\t\t\t\t(mergedRootProps as { ref?: React.Ref<TElement> } | undefined)?.ref\n\t\t\t\t),\n\t\t\t};\n\t\t},\n\t\t[extraRootProps, classNames?.base, orientation, refCallBack, usage]\n\t);\n\n\tconst getItemProps: DragScrollResult<TElement, TItemElement>[\"getItemProps\"] = useCallback(\n\t\t(itemProps) => {\n\t\t\tconst mergedItemProps = mergeTwoProps(extraItemProps, itemProps);\n\n\t\t\treturn {\n\t\t\t\t...mergedItemProps,\n\t\t\t\tclassName: cnMerge(\"snap-center snap-always\", classNames?.item, mergedItemProps.className),\n\t\t\t\t\"data-part\": \"item\",\n\t\t\t\t\"data-scope\": \"drag-scroll\",\n\t\t\t\t\"data-slot\": \"drag-scroll-item\",\n\t\t\t};\n\t\t},\n\t\t[extraItemProps, classNames?.item]\n\t);\n\n\tconst result = useMemo(() => ({ getItemProps, getRootProps }), [getItemProps, getRootProps]);\n\n\treturn result;\n};\n\nexport { useDragScroll };\n"],"mappings":"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"}
|
|
@@ -311,7 +311,9 @@ type RenderPreviewFn = (context: RenderPropContext) => RenderPreviewObject;
|
|
|
311
311
|
type RenderPreview = RenderPreviewFn | RenderPreviewObject;
|
|
312
312
|
type DropZoneFileItemPreviewProps = Omit<PartInputProps["fileItemPreview"], "children"> & Partial<Pick<FileItemContextType, "fileState">> & {
|
|
313
313
|
asChild?: boolean;
|
|
314
|
-
children?: react4.ReactNode | ((context: RenderPropContext
|
|
314
|
+
children?: react4.ReactNode | ((context: RenderPropContext & {
|
|
315
|
+
fallbackPreview: () => react4.ReactNode;
|
|
316
|
+
}) => react4.ReactNode);
|
|
315
317
|
renderPreview?: boolean | RenderPreview;
|
|
316
318
|
};
|
|
317
319
|
declare function DropZoneFileItemPreview<TElement extends react4.ElementType>(props: PolymorphicPropsStrict<TElement, DropZoneFileItemPreviewProps>): react_jsx_runtime36.JSX.Element | null;
|