@yahoo/uds-mobile 2.18.0 → 2.20.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/components/Modal/Modal.cjs +396 -0
- package/dist/components/Modal/Modal.d.cts +9 -0
- package/dist/components/Modal/Modal.d.cts.map +1 -0
- package/dist/components/Modal/Modal.d.ts +9 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -0
- package/dist/components/Modal/Modal.js +395 -0
- package/dist/components/Modal/Modal.js.map +1 -0
- package/dist/components/Modal/ModalActions.cjs +47 -0
- package/dist/components/Modal/ModalActions.d.cts +9 -0
- package/dist/components/Modal/ModalActions.d.cts.map +1 -0
- package/dist/components/Modal/ModalActions.d.ts +9 -0
- package/dist/components/Modal/ModalActions.d.ts.map +1 -0
- package/dist/components/Modal/ModalActions.js +47 -0
- package/dist/components/Modal/ModalActions.js.map +1 -0
- package/dist/components/Modal/ModalContent.cjs +41 -0
- package/dist/components/Modal/ModalContent.d.cts +9 -0
- package/dist/components/Modal/ModalContent.d.cts.map +1 -0
- package/dist/components/Modal/ModalContent.d.ts +9 -0
- package/dist/components/Modal/ModalContent.d.ts.map +1 -0
- package/dist/components/Modal/ModalContent.js +41 -0
- package/dist/components/Modal/ModalContent.js.map +1 -0
- package/dist/components/Modal/ModalContext.cjs +14 -0
- package/dist/components/Modal/ModalContext.d.cts +10 -0
- package/dist/components/Modal/ModalContext.d.cts.map +1 -0
- package/dist/components/Modal/ModalContext.d.ts +10 -0
- package/dist/components/Modal/ModalContext.d.ts.map +1 -0
- package/dist/components/Modal/ModalContext.js +13 -0
- package/dist/components/Modal/ModalContext.js.map +1 -0
- package/dist/components/Modal/ModalDescription.cjs +21 -0
- package/dist/components/Modal/ModalDescription.d.cts +9 -0
- package/dist/components/Modal/ModalDescription.d.cts.map +1 -0
- package/dist/components/Modal/ModalDescription.d.ts +9 -0
- package/dist/components/Modal/ModalDescription.d.ts.map +1 -0
- package/dist/components/Modal/ModalDescription.js +21 -0
- package/dist/components/Modal/ModalDescription.js.map +1 -0
- package/dist/components/Modal/ModalTitle.cjs +22 -0
- package/dist/components/Modal/ModalTitle.d.cts +9 -0
- package/dist/components/Modal/ModalTitle.d.cts.map +1 -0
- package/dist/components/Modal/ModalTitle.d.ts +9 -0
- package/dist/components/Modal/ModalTitle.d.ts.map +1 -0
- package/dist/components/Modal/ModalTitle.js +22 -0
- package/dist/components/Modal/ModalTitle.js.map +1 -0
- package/dist/components/Modal/index.cjs +12 -0
- package/dist/components/Modal/index.d.cts +8 -0
- package/dist/components/Modal/index.d.ts +8 -0
- package/dist/components/Modal/index.js +7 -0
- package/dist/components/Modal/types.cjs +1 -0
- package/dist/components/Modal/types.d.cts +111 -0
- package/dist/components/Modal/types.d.cts.map +1 -0
- package/dist/components/Modal/types.d.ts +111 -0
- package/dist/components/Modal/types.d.ts.map +1 -0
- package/dist/components/Modal/types.js +1 -0
- package/dist/components/Modal/utils.cjs +59 -0
- package/dist/components/Modal/utils.d.cts +28 -0
- package/dist/components/Modal/utils.d.cts.map +1 -0
- package/dist/components/Modal/utils.d.ts +28 -0
- package/dist/components/Modal/utils.d.ts.map +1 -0
- package/dist/components/Modal/utils.js +56 -0
- package/dist/components/Modal/utils.js.map +1 -0
- package/dist/components/Pagination/Pagination.cjs +75 -0
- package/dist/components/Pagination/Pagination.d.cts +40 -0
- package/dist/components/Pagination/Pagination.d.cts.map +1 -0
- package/dist/components/Pagination/Pagination.d.ts +40 -0
- package/dist/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination/Pagination.js +75 -0
- package/dist/components/Pagination/Pagination.js.map +1 -0
- package/dist/components/Pagination/PaginationEllipsis.cjs +64 -0
- package/dist/components/Pagination/PaginationEllipsis.d.cts +21 -0
- package/dist/components/Pagination/PaginationEllipsis.d.cts.map +1 -0
- package/dist/components/Pagination/PaginationEllipsis.d.ts +21 -0
- package/dist/components/Pagination/PaginationEllipsis.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationEllipsis.js +64 -0
- package/dist/components/Pagination/PaginationEllipsis.js.map +1 -0
- package/dist/components/Pagination/PaginationItem.cjs +68 -0
- package/dist/components/Pagination/PaginationItem.d.cts +24 -0
- package/dist/components/Pagination/PaginationItem.d.cts.map +1 -0
- package/dist/components/Pagination/PaginationItem.d.ts +24 -0
- package/dist/components/Pagination/PaginationItem.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationItem.js +68 -0
- package/dist/components/Pagination/PaginationItem.js.map +1 -0
- package/dist/components/Pagination/PaginationLink.cjs +68 -0
- package/dist/components/Pagination/PaginationLink.d.cts +25 -0
- package/dist/components/Pagination/PaginationLink.d.cts.map +1 -0
- package/dist/components/Pagination/PaginationLink.d.ts +25 -0
- package/dist/components/Pagination/PaginationLink.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationLink.js +68 -0
- package/dist/components/Pagination/PaginationLink.js.map +1 -0
- package/dist/components/Pagination/PaginationNext.cjs +72 -0
- package/dist/components/Pagination/PaginationNext.d.cts +24 -0
- package/dist/components/Pagination/PaginationNext.d.cts.map +1 -0
- package/dist/components/Pagination/PaginationNext.d.ts +24 -0
- package/dist/components/Pagination/PaginationNext.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationNext.js +72 -0
- package/dist/components/Pagination/PaginationNext.js.map +1 -0
- package/dist/components/Pagination/PaginationNumbers.cjs +50 -0
- package/dist/components/Pagination/PaginationNumbers.d.cts +23 -0
- package/dist/components/Pagination/PaginationNumbers.d.cts.map +1 -0
- package/dist/components/Pagination/PaginationNumbers.d.ts +23 -0
- package/dist/components/Pagination/PaginationNumbers.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationNumbers.js +50 -0
- package/dist/components/Pagination/PaginationNumbers.js.map +1 -0
- package/dist/components/Pagination/PaginationPrev.cjs +72 -0
- package/dist/components/Pagination/PaginationPrev.d.cts +24 -0
- package/dist/components/Pagination/PaginationPrev.d.cts.map +1 -0
- package/dist/components/Pagination/PaginationPrev.d.ts +24 -0
- package/dist/components/Pagination/PaginationPrev.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationPrev.js +72 -0
- package/dist/components/Pagination/PaginationPrev.js.map +1 -0
- package/dist/components/Pagination/computeVisiblePages.cjs +21 -0
- package/dist/components/Pagination/computeVisiblePages.d.cts +19 -0
- package/dist/components/Pagination/computeVisiblePages.d.cts.map +1 -0
- package/dist/components/Pagination/computeVisiblePages.d.ts +19 -0
- package/dist/components/Pagination/computeVisiblePages.d.ts.map +1 -0
- package/dist/components/Pagination/computeVisiblePages.js +22 -0
- package/dist/components/Pagination/computeVisiblePages.js.map +1 -0
- package/dist/components/Pagination/ellipsisDefault.cjs +28 -0
- package/dist/components/Pagination/ellipsisDefault.d.cts +11 -0
- package/dist/components/Pagination/ellipsisDefault.d.cts.map +1 -0
- package/dist/components/Pagination/ellipsisDefault.d.ts +11 -0
- package/dist/components/Pagination/ellipsisDefault.d.ts.map +1 -0
- package/dist/components/Pagination/ellipsisDefault.js +29 -0
- package/dist/components/Pagination/ellipsisDefault.js.map +1 -0
- package/dist/components/Pagination/ellipsisNone.cjs +24 -0
- package/dist/components/Pagination/ellipsisNone.d.cts +11 -0
- package/dist/components/Pagination/ellipsisNone.d.cts.map +1 -0
- package/dist/components/Pagination/ellipsisNone.d.ts +11 -0
- package/dist/components/Pagination/ellipsisNone.d.ts.map +1 -0
- package/dist/components/Pagination/ellipsisNone.js +25 -0
- package/dist/components/Pagination/ellipsisNone.js.map +1 -0
- package/dist/components/Pagination/index.cjs +18 -0
- package/dist/components/Pagination/index.d.cts +10 -0
- package/dist/components/Pagination/index.d.ts +10 -0
- package/dist/components/Pagination/index.js +10 -0
- package/dist/components/Pagination/paginationContext.cjs +42 -0
- package/dist/components/Pagination/paginationContext.d.cts +34 -0
- package/dist/components/Pagination/paginationContext.d.cts.map +1 -0
- package/dist/components/Pagination/paginationContext.d.ts +34 -0
- package/dist/components/Pagination/paginationContext.d.ts.map +1 -0
- package/dist/components/Pagination/paginationContext.js +38 -0
- package/dist/components/Pagination/paginationContext.js.map +1 -0
- package/dist/components/Pagination/paginationDefaultComponents.cjs +68 -0
- package/dist/components/Pagination/paginationDefaultComponents.d.cts +17 -0
- package/dist/components/Pagination/paginationDefaultComponents.d.cts.map +1 -0
- package/dist/components/Pagination/paginationDefaultComponents.d.ts +17 -0
- package/dist/components/Pagination/paginationDefaultComponents.d.ts.map +1 -0
- package/dist/components/Pagination/paginationDefaultComponents.js +69 -0
- package/dist/components/Pagination/paginationDefaultComponents.js.map +1 -0
- package/dist/components/Pagination/paginationTheme.cjs +67 -0
- package/dist/components/Pagination/paginationTheme.d.cts +28 -0
- package/dist/components/Pagination/paginationTheme.d.cts.map +1 -0
- package/dist/components/Pagination/paginationTheme.d.ts +28 -0
- package/dist/components/Pagination/paginationTheme.d.ts.map +1 -0
- package/dist/components/Pagination/paginationTheme.js +62 -0
- package/dist/components/Pagination/paginationTheme.js.map +1 -0
- package/dist/components/Pagination/range.cjs +10 -0
- package/dist/components/Pagination/range.d.cts +6 -0
- package/dist/components/Pagination/range.d.cts.map +1 -0
- package/dist/components/Pagination/range.d.ts +6 -0
- package/dist/components/Pagination/range.d.ts.map +1 -0
- package/dist/components/Pagination/range.js +11 -0
- package/dist/components/Pagination/range.js.map +1 -0
- package/dist/components/Pagination/usePaginationControlStyles.cjs +78 -0
- package/dist/components/Pagination/usePaginationControlStyles.d.cts +26 -0
- package/dist/components/Pagination/usePaginationControlStyles.d.cts.map +1 -0
- package/dist/components/Pagination/usePaginationControlStyles.d.ts +26 -0
- package/dist/components/Pagination/usePaginationControlStyles.d.ts.map +1 -0
- package/dist/components/Pagination/usePaginationControlStyles.js +78 -0
- package/dist/components/Pagination/usePaginationControlStyles.js.map +1 -0
- package/dist/jest/bun-test-guard.cjs +8 -0
- package/dist/jest/bun-test-guard.d.cts +2 -0
- package/dist/jest/bun-test-guard.d.ts +2 -0
- package/dist/jest/bun-test-guard.js +10 -0
- package/dist/jest/bun-test-guard.js.map +1 -0
- package/dist/jest/mocks/gesture-handler.cjs +29 -0
- package/dist/jest/mocks/gesture-handler.d.cts +27 -2
- package/dist/jest/mocks/gesture-handler.d.cts.map +1 -1
- package/dist/jest/mocks/gesture-handler.d.ts +27 -2
- package/dist/jest/mocks/gesture-handler.d.ts.map +1 -1
- package/dist/jest/mocks/gesture-handler.js +22 -1
- package/dist/jest/mocks/gesture-handler.js.map +1 -1
- package/dist/jest/mocks/styles.cjs +62 -0
- package/dist/jest/mocks/styles.d.cts +4 -2
- package/dist/jest/mocks/styles.d.cts.map +1 -1
- package/dist/jest/mocks/styles.d.ts +4 -2
- package/dist/jest/mocks/styles.d.ts.map +1 -1
- package/dist/jest/mocks/styles.js +61 -1
- package/dist/jest/mocks/styles.js.map +1 -1
- package/dist/jest/setup.cjs +8 -28
- package/dist/jest/setup.d.cts.map +1 -1
- package/dist/jest/setup.d.ts.map +1 -1
- package/dist/jest/setup.js +8 -28
- package/dist/jest/setup.js.map +1 -1
- package/dist/types/dist/index.d.cts +83 -1
- package/dist/types/dist/index.d.cts.map +1 -1
- package/dist/types/dist/index.d.ts +83 -1
- package/dist/types/dist/index.d.ts.map +1 -1
- package/generated/styles.cjs +75 -0
- package/generated/styles.d.ts +29 -0
- package/generated/styles.mjs +75 -0
- package/generated/unistyles.d.ts +69 -0
- package/package.json +21 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
import { AndroidBackHandler } from "../AndroidBackHandler.js";
|
|
3
|
+
import { Box } from "../Box.js";
|
|
4
|
+
import { IconSlot } from "../IconSlot.js";
|
|
5
|
+
import { Text as Text$1 } from "../Text.js";
|
|
6
|
+
import { AnimatedPressable } from "../Pressable.js";
|
|
7
|
+
import { Scrim } from "../Scrim.js";
|
|
8
|
+
import { OverlayPortal } from "../internal/Overlay/OverlayPortal.js";
|
|
9
|
+
import { ModalContext } from "./ModalContext.js";
|
|
10
|
+
import { ModalActions } from "./ModalActions.js";
|
|
11
|
+
import { ModalContent } from "./ModalContent.js";
|
|
12
|
+
import { ModalDescription } from "./ModalDescription.js";
|
|
13
|
+
import { ModalTitle } from "./ModalTitle.js";
|
|
14
|
+
import { getEventPagePoint, resolveModalDimension, separateChildren, shouldDismissModalRelease } from "./utils.js";
|
|
15
|
+
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
16
|
+
import { AccessibilityInfo, Platform, ScrollView, StyleSheet, View } from "react-native";
|
|
17
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { modalStyles } from "../../../generated/styles";
|
|
19
|
+
import Animated, { Easing, interpolate, useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
|
|
20
|
+
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
21
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
22
|
+
//#region src/components/Modal/Modal.tsx
|
|
23
|
+
const ANIMATION_DURATION_IN = 400;
|
|
24
|
+
const ANIMATION_DURATION_OUT = 250;
|
|
25
|
+
const ANIMATION_EASING_IN = Easing.bezier(.3, .4, .2, 1);
|
|
26
|
+
const ANIMATION_EASING_OUT = Easing.bezier(.6, 0, .7, .6);
|
|
27
|
+
const HIDDEN_SCALE = .95;
|
|
28
|
+
const HIDDEN_PROGRESS = 1;
|
|
29
|
+
const VISIBLE_PROGRESS = 0;
|
|
30
|
+
const SCROLL_DISMISS_SUPPRESSION_MS = 150;
|
|
31
|
+
const SCROLL_OFFSET_THRESHOLD = 1;
|
|
32
|
+
function usePrefersReducedMotion() {
|
|
33
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
let isMounted = true;
|
|
36
|
+
AccessibilityInfo.isReduceMotionEnabled().then((isReduceMotionEnabled) => {
|
|
37
|
+
if (isMounted) setPrefersReducedMotion(isReduceMotionEnabled);
|
|
38
|
+
});
|
|
39
|
+
const subscription = AccessibilityInfo.addEventListener("reduceMotionChanged", (isReduceMotionEnabled) => {
|
|
40
|
+
setPrefersReducedMotion(isReduceMotionEnabled);
|
|
41
|
+
});
|
|
42
|
+
return () => {
|
|
43
|
+
isMounted = false;
|
|
44
|
+
subscription.remove();
|
|
45
|
+
};
|
|
46
|
+
}, []);
|
|
47
|
+
return prefersReducedMotion;
|
|
48
|
+
}
|
|
49
|
+
const Modal = memo(function Modal({ children, open, onClose, onOpen, portal = true, includeScrim, dismissible = true, hideDismissButton = false, reduceMotion = false, closeIcon = "Cross", closeAriaLabel = "Close", closeAccessibilityLabel, maxWidth = "auto", maxHeight = "auto", fullWidth = false, fullHeight = false, title: titleProp, description: descriptionProp, content: contentProp, actions: actionsProp, scrollBehavior = "outside", useFullWindowOverlay = true, blurTarget, style, ref, onLayout, ...viewProps }) {
|
|
50
|
+
modalStyles.useVariants({});
|
|
51
|
+
const surfaceRef = useRef(null);
|
|
52
|
+
const prevOpen = useRef(open);
|
|
53
|
+
const progress = useSharedValue(HIDDEN_PROGRESS);
|
|
54
|
+
const closePressProgress = useSharedValue(0);
|
|
55
|
+
const presenceState = useRef(open ? "open" : "closed");
|
|
56
|
+
const didModalScrollDuringGesture = useRef(false);
|
|
57
|
+
const isModalScrollInteracting = useRef(false);
|
|
58
|
+
const modalScrollDismissTimeout = useRef(null);
|
|
59
|
+
const modalScrollStartOffset = useRef(null);
|
|
60
|
+
const [, forcePresenceRender] = useState(0);
|
|
61
|
+
const prefersReducedMotion = usePrefersReducedMotion();
|
|
62
|
+
const reducedMotion = reduceMotion || prefersReducedMotion;
|
|
63
|
+
const safeAreaInsets = useSafeAreaInsets();
|
|
64
|
+
if (open) presenceState.current = "open";
|
|
65
|
+
else if (presenceState.current === "open") presenceState.current = "closing";
|
|
66
|
+
const isRendered = open || presenceState.current === "closing";
|
|
67
|
+
const { title: modalTitle, description: modalDescription, content: modalContent, actions: modalActions } = separateChildren(children);
|
|
68
|
+
const hasTitleOrDescription = !!(modalTitle || titleProp || modalDescription || descriptionProp);
|
|
69
|
+
const shouldRenderHeader = !hideDismissButton || hasTitleOrDescription;
|
|
70
|
+
const hasContent = !!(modalContent || contentProp);
|
|
71
|
+
const shouldRenderScrim = includeScrim ?? true;
|
|
72
|
+
const closeLabel = closeAccessibilityLabel ?? closeAriaLabel;
|
|
73
|
+
const durationIn = reducedMotion ? 0 : ANIMATION_DURATION_IN;
|
|
74
|
+
const durationOut = reducedMotion ? 0 : ANIMATION_DURATION_OUT;
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (open && !prevOpen.current) onOpen?.();
|
|
77
|
+
prevOpen.current = open;
|
|
78
|
+
}, [open, onOpen]);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (open) {
|
|
81
|
+
progress.value = HIDDEN_PROGRESS;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!isRendered) return;
|
|
85
|
+
progress.value = withTiming(HIDDEN_PROGRESS, {
|
|
86
|
+
duration: durationOut,
|
|
87
|
+
easing: ANIMATION_EASING_OUT
|
|
88
|
+
});
|
|
89
|
+
const timeout = setTimeout(() => {
|
|
90
|
+
if (presenceState.current === "closing") {
|
|
91
|
+
presenceState.current = "closed";
|
|
92
|
+
forcePresenceRender((revision) => revision + 1);
|
|
93
|
+
}
|
|
94
|
+
}, durationOut);
|
|
95
|
+
return () => clearTimeout(timeout);
|
|
96
|
+
}, [
|
|
97
|
+
durationOut,
|
|
98
|
+
isRendered,
|
|
99
|
+
open,
|
|
100
|
+
progress
|
|
101
|
+
]);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (!open || !isRendered) return;
|
|
104
|
+
if (durationIn === 0) {
|
|
105
|
+
progress.value = VISIBLE_PROGRESS;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const animationFrame = requestAnimationFrame(() => {
|
|
109
|
+
progress.value = withTiming(VISIBLE_PROGRESS, {
|
|
110
|
+
duration: durationIn,
|
|
111
|
+
easing: ANIMATION_EASING_IN
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
return () => cancelAnimationFrame(animationFrame);
|
|
115
|
+
}, [
|
|
116
|
+
durationIn,
|
|
117
|
+
isRendered,
|
|
118
|
+
open,
|
|
119
|
+
progress
|
|
120
|
+
]);
|
|
121
|
+
const handleDismiss = useCallback(() => {
|
|
122
|
+
onClose?.();
|
|
123
|
+
}, [onClose]);
|
|
124
|
+
const clearModalScrollDismissTimeout = useCallback(() => {
|
|
125
|
+
if (modalScrollDismissTimeout.current) {
|
|
126
|
+
clearTimeout(modalScrollDismissTimeout.current);
|
|
127
|
+
modalScrollDismissTimeout.current = null;
|
|
128
|
+
}
|
|
129
|
+
}, []);
|
|
130
|
+
const handleModalScrollInteractionBegin = useCallback((event) => {
|
|
131
|
+
clearModalScrollDismissTimeout();
|
|
132
|
+
isModalScrollInteracting.current = true;
|
|
133
|
+
didModalScrollDuringGesture.current = false;
|
|
134
|
+
modalScrollStartOffset.current = event.nativeEvent.contentOffset;
|
|
135
|
+
}, [clearModalScrollDismissTimeout]);
|
|
136
|
+
const handleModalScroll = useCallback((event) => {
|
|
137
|
+
if (!isModalScrollInteracting.current || didModalScrollDuringGesture.current) return;
|
|
138
|
+
const startOffset = modalScrollStartOffset.current;
|
|
139
|
+
const currentOffset = event.nativeEvent.contentOffset;
|
|
140
|
+
if (!startOffset) return;
|
|
141
|
+
const movedX = Math.abs(currentOffset.x - startOffset.x);
|
|
142
|
+
const movedY = Math.abs(currentOffset.y - startOffset.y);
|
|
143
|
+
if (movedX > SCROLL_OFFSET_THRESHOLD || movedY > SCROLL_OFFSET_THRESHOLD) didModalScrollDuringGesture.current = true;
|
|
144
|
+
}, []);
|
|
145
|
+
const handleModalScrollInteractionEnd = useCallback(() => {
|
|
146
|
+
clearModalScrollDismissTimeout();
|
|
147
|
+
modalScrollDismissTimeout.current = setTimeout(() => {
|
|
148
|
+
isModalScrollInteracting.current = false;
|
|
149
|
+
didModalScrollDuringGesture.current = false;
|
|
150
|
+
modalScrollDismissTimeout.current = null;
|
|
151
|
+
modalScrollStartOffset.current = null;
|
|
152
|
+
}, SCROLL_DISMISS_SUPPRESSION_MS);
|
|
153
|
+
}, [clearModalScrollDismissTimeout]);
|
|
154
|
+
useEffect(() => clearModalScrollDismissTimeout, [clearModalScrollDismissTimeout]);
|
|
155
|
+
const handleScrimRelease = useCallback((absoluteX, absoluteY) => {
|
|
156
|
+
if (!dismissible) return;
|
|
157
|
+
if (!surfaceRef.current?.measureInWindow) return;
|
|
158
|
+
surfaceRef.current.measureInWindow((x, y, width, height) => {
|
|
159
|
+
if (shouldDismissModalRelease({
|
|
160
|
+
x: absoluteX,
|
|
161
|
+
y: absoluteY
|
|
162
|
+
}, {
|
|
163
|
+
x,
|
|
164
|
+
y,
|
|
165
|
+
width,
|
|
166
|
+
height
|
|
167
|
+
})) onClose?.();
|
|
168
|
+
});
|
|
169
|
+
}, [dismissible, onClose]);
|
|
170
|
+
const handleOverlayTouchEndCapture = useCallback((event) => {
|
|
171
|
+
if (isModalScrollInteracting.current && didModalScrollDuringGesture.current) return;
|
|
172
|
+
const pagePoint = getEventPagePoint(event);
|
|
173
|
+
if (!pagePoint) return;
|
|
174
|
+
handleScrimRelease(pagePoint.x, pagePoint.y);
|
|
175
|
+
}, [handleScrimRelease]);
|
|
176
|
+
const setSurfaceRef = useCallback((node) => {
|
|
177
|
+
surfaceRef.current = node;
|
|
178
|
+
if (typeof ref === "function") ref(node);
|
|
179
|
+
else if (ref) ref.current = node;
|
|
180
|
+
}, [ref]);
|
|
181
|
+
const handleClosePressIn = useCallback(() => {
|
|
182
|
+
closePressProgress.value = withTiming(1, { duration: reducedMotion ? 0 : 120 });
|
|
183
|
+
}, [closePressProgress, reducedMotion]);
|
|
184
|
+
const handleClosePressOut = useCallback(() => {
|
|
185
|
+
closePressProgress.value = withTiming(0, { duration: reducedMotion ? 0 : 120 });
|
|
186
|
+
}, [closePressProgress, reducedMotion]);
|
|
187
|
+
const animatedSurfaceStyle = useAnimatedStyle(() => ({
|
|
188
|
+
opacity: interpolate(progress.value, [VISIBLE_PROGRESS, HIDDEN_PROGRESS], [1, 0], "clamp"),
|
|
189
|
+
transform: [{ scale: interpolate(progress.value, [VISIBLE_PROGRESS, HIDDEN_PROGRESS], [1, HIDDEN_SCALE], "clamp") }]
|
|
190
|
+
}));
|
|
191
|
+
const animatedCloseIconContainerStyle = useAnimatedStyle(() => ({ backgroundColor: `rgba(29, 34, 40, ${interpolate(closePressProgress.value, [0, 1], [0, .15], "clamp").toFixed(3)})` }));
|
|
192
|
+
const modalContextValue = useMemo(() => ({
|
|
193
|
+
scrollBehavior,
|
|
194
|
+
hasContent,
|
|
195
|
+
onScroll: handleModalScroll,
|
|
196
|
+
onScrollInteractionBegin: handleModalScrollInteractionBegin,
|
|
197
|
+
onScrollInteractionEnd: handleModalScrollInteractionEnd,
|
|
198
|
+
shouldRenderHeader
|
|
199
|
+
}), [
|
|
200
|
+
handleModalScroll,
|
|
201
|
+
handleModalScrollInteractionBegin,
|
|
202
|
+
handleModalScrollInteractionEnd,
|
|
203
|
+
hasContent,
|
|
204
|
+
scrollBehavior,
|
|
205
|
+
shouldRenderHeader
|
|
206
|
+
]);
|
|
207
|
+
if (!isRendered) return null;
|
|
208
|
+
const rootTokens = StyleSheet.flatten(modalStyles.root);
|
|
209
|
+
const gutter = StyleSheet.flatten(modalStyles.scrim).padding ?? 0;
|
|
210
|
+
const blurIntensity = rootTokens.backgroundBlurRadius ?? 0;
|
|
211
|
+
const showBlurBox = blurIntensity > 0 && (Platform.OS === "ios" || blurTarget != null);
|
|
212
|
+
const rootBackgroundColor = showBlurBox ? "transparent" : blurIntensity > 0 ? rootTokens.backgroundBlurColor ?? rootTokens.backgroundColor : rootTokens.backgroundColor;
|
|
213
|
+
const rootBorderRadius = rootTokens.borderRadius ?? 0;
|
|
214
|
+
const rootMaxHeight = scrollBehavior === "inside" ? resolveModalDimension(maxHeight) : void 0;
|
|
215
|
+
const shouldFillHeight = fullHeight && scrollBehavior === "inside" && rootMaxHeight !== void 0;
|
|
216
|
+
const headerSpacingBottom = hasContent ? modalStyles.root.paddingVertical ?? 0 : 0;
|
|
217
|
+
const closeIconContainerSize = (modalStyles.closeIcon.fontSize ?? 0) + (modalStyles.closeIconContainer.padding ?? 0) * 2;
|
|
218
|
+
const closeIconOffset = closeIconContainerSize / 2;
|
|
219
|
+
const closeIconTop = modalStyles.root.paddingVertical ?? 0;
|
|
220
|
+
const closeIconRight = modalStyles.spacingHorizontal.paddingHorizontal ?? 0;
|
|
221
|
+
const surface = /* @__PURE__ */ jsxs(Animated.View, {
|
|
222
|
+
ref: setSurfaceRef,
|
|
223
|
+
accessibilityViewIsModal: true,
|
|
224
|
+
importantForAccessibility: "yes",
|
|
225
|
+
...viewProps,
|
|
226
|
+
onLayout,
|
|
227
|
+
style: [
|
|
228
|
+
modalStyles.root,
|
|
229
|
+
internalStyles.surface,
|
|
230
|
+
{
|
|
231
|
+
backgroundColor: rootBackgroundColor,
|
|
232
|
+
maxHeight: rootMaxHeight,
|
|
233
|
+
maxWidth: resolveModalDimension(maxWidth),
|
|
234
|
+
height: shouldFillHeight ? rootMaxHeight : void 0,
|
|
235
|
+
width: fullWidth ? "100%" : void 0,
|
|
236
|
+
borderRadius: rootBorderRadius,
|
|
237
|
+
overflow: showBlurBox ? "hidden" : void 0
|
|
238
|
+
},
|
|
239
|
+
animatedSurfaceStyle,
|
|
240
|
+
style
|
|
241
|
+
],
|
|
242
|
+
children: [showBlurBox && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Box, {
|
|
243
|
+
style: StyleSheet.absoluteFill,
|
|
244
|
+
blur: blurIntensity,
|
|
245
|
+
blurTarget
|
|
246
|
+
}), /* @__PURE__ */ jsx(View, {
|
|
247
|
+
pointerEvents: "none",
|
|
248
|
+
style: [StyleSheet.absoluteFill, {
|
|
249
|
+
backgroundColor: rootTokens.backgroundBlurColor,
|
|
250
|
+
borderRadius: rootBorderRadius
|
|
251
|
+
}]
|
|
252
|
+
})] }), /* @__PURE__ */ jsxs(ModalContext.Provider, {
|
|
253
|
+
value: modalContextValue,
|
|
254
|
+
children: [
|
|
255
|
+
!hideDismissButton && closeIcon !== false && /* @__PURE__ */ jsx(AnimatedPressable, {
|
|
256
|
+
accessibilityLabel: closeLabel,
|
|
257
|
+
accessibilityRole: "button",
|
|
258
|
+
hitSlop: 12,
|
|
259
|
+
onPress: onClose,
|
|
260
|
+
onPressIn: handleClosePressIn,
|
|
261
|
+
onPressOut: handleClosePressOut,
|
|
262
|
+
style: [
|
|
263
|
+
modalStyles.closeIconContainer,
|
|
264
|
+
internalStyles.closeIconContainer,
|
|
265
|
+
{
|
|
266
|
+
borderRadius: closeIconContainerSize,
|
|
267
|
+
right: closeIconRight,
|
|
268
|
+
top: closeIconTop,
|
|
269
|
+
transform: [{ translateX: closeIconOffset }, { translateY: -closeIconOffset }]
|
|
270
|
+
},
|
|
271
|
+
animatedCloseIconContainerStyle
|
|
272
|
+
],
|
|
273
|
+
children: /* @__PURE__ */ jsx(IconSlot, {
|
|
274
|
+
icon: closeIcon,
|
|
275
|
+
variant: "outline",
|
|
276
|
+
size: modalStyles.closeIcon.iconSizeToken ?? "md",
|
|
277
|
+
style: modalStyles.closeIcon,
|
|
278
|
+
accessibilityElementsHidden: true,
|
|
279
|
+
importantForAccessibility: "no"
|
|
280
|
+
})
|
|
281
|
+
}),
|
|
282
|
+
shouldRenderHeader && /* @__PURE__ */ jsx(View, {
|
|
283
|
+
style: [
|
|
284
|
+
modalStyles.spacingHorizontal,
|
|
285
|
+
internalStyles.header,
|
|
286
|
+
{ marginBottom: headerSpacingBottom }
|
|
287
|
+
],
|
|
288
|
+
children: hasTitleOrDescription && /* @__PURE__ */ jsxs(View, {
|
|
289
|
+
style: [internalStyles.titleDescriptionWrapper, { gap: modalStyles.titleDescriptionWrapper.gap }],
|
|
290
|
+
children: [modalTitle || (titleProp ? /* @__PURE__ */ jsx(ModalTitle, { children: titleProp }) : null), modalDescription || (descriptionProp ? /* @__PURE__ */ jsx(ModalDescription, { children: descriptionProp }) : null)]
|
|
291
|
+
})
|
|
292
|
+
}),
|
|
293
|
+
modalContent || (contentProp ? /* @__PURE__ */ jsx(ModalContent, { children: typeof contentProp === "string" || typeof contentProp === "number" ? /* @__PURE__ */ jsx(Text$1, {
|
|
294
|
+
color: "secondary",
|
|
295
|
+
variant: "ui1",
|
|
296
|
+
children: contentProp
|
|
297
|
+
}) : contentProp }) : /* @__PURE__ */ jsx(View, { style: internalStyles.grow })),
|
|
298
|
+
modalActions || (actionsProp ? /* @__PURE__ */ jsx(ModalActions, { children: actionsProp }) : null)
|
|
299
|
+
]
|
|
300
|
+
})]
|
|
301
|
+
});
|
|
302
|
+
const positionerInsetStyle = {
|
|
303
|
+
paddingTop: safeAreaInsets.top + gutter,
|
|
304
|
+
paddingRight: safeAreaInsets.right + gutter,
|
|
305
|
+
paddingBottom: safeAreaInsets.bottom + gutter,
|
|
306
|
+
paddingLeft: safeAreaInsets.left + gutter
|
|
307
|
+
};
|
|
308
|
+
const positionerStyle = [
|
|
309
|
+
internalStyles.positioner,
|
|
310
|
+
shouldFillHeight && internalStyles.fullHeightPositioner,
|
|
311
|
+
positionerInsetStyle
|
|
312
|
+
];
|
|
313
|
+
const outsidePositionerStyle = [internalStyles.outsidePositioner, positionerInsetStyle];
|
|
314
|
+
const positionedSurface = /* @__PURE__ */ jsx(View, {
|
|
315
|
+
style: positionerStyle,
|
|
316
|
+
testID: "uds-modal-positioner",
|
|
317
|
+
children: surface
|
|
318
|
+
});
|
|
319
|
+
const overlay = /* @__PURE__ */ jsx(GestureHandlerRootView, {
|
|
320
|
+
style: StyleSheet.absoluteFill,
|
|
321
|
+
children: /* @__PURE__ */ jsxs(View, {
|
|
322
|
+
onTouchEndCapture: dismissible ? handleOverlayTouchEndCapture : void 0,
|
|
323
|
+
pointerEvents: "auto",
|
|
324
|
+
style: StyleSheet.absoluteFill,
|
|
325
|
+
testID: "uds-modal-overlay",
|
|
326
|
+
children: [
|
|
327
|
+
/* @__PURE__ */ jsx(AndroidBackHandler, {
|
|
328
|
+
isOpen: open,
|
|
329
|
+
dismissible,
|
|
330
|
+
onDismiss: handleDismiss
|
|
331
|
+
}),
|
|
332
|
+
shouldRenderScrim && /* @__PURE__ */ jsx(Scrim, {
|
|
333
|
+
translateY: progress,
|
|
334
|
+
openTranslateY: VISIBLE_PROGRESS,
|
|
335
|
+
closedTranslateY: HIDDEN_PROGRESS,
|
|
336
|
+
dismissible: false,
|
|
337
|
+
onDismiss: handleDismiss,
|
|
338
|
+
blurTarget
|
|
339
|
+
}),
|
|
340
|
+
scrollBehavior === "outside" ? /* @__PURE__ */ jsx(ScrollView, {
|
|
341
|
+
alwaysBounceVertical: false,
|
|
342
|
+
bounces: false,
|
|
343
|
+
keyboardShouldPersistTaps: "handled",
|
|
344
|
+
onMomentumScrollEnd: handleModalScrollInteractionEnd,
|
|
345
|
+
onScroll: handleModalScroll,
|
|
346
|
+
onScrollBeginDrag: handleModalScrollInteractionBegin,
|
|
347
|
+
onScrollEndDrag: handleModalScrollInteractionEnd,
|
|
348
|
+
overScrollMode: "never",
|
|
349
|
+
scrollEventThrottle: 16,
|
|
350
|
+
contentContainerStyle: outsidePositionerStyle,
|
|
351
|
+
style: StyleSheet.absoluteFill,
|
|
352
|
+
children: surface
|
|
353
|
+
}) : positionedSurface
|
|
354
|
+
]
|
|
355
|
+
})
|
|
356
|
+
});
|
|
357
|
+
if (!portal) return overlay;
|
|
358
|
+
return /* @__PURE__ */ jsx(OverlayPortal, {
|
|
359
|
+
useFullWindowOverlay,
|
|
360
|
+
children: overlay
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
Modal.displayName = "Modal";
|
|
364
|
+
const internalStyles = StyleSheet.create({
|
|
365
|
+
positioner: {
|
|
366
|
+
alignItems: "center",
|
|
367
|
+
flexGrow: 1,
|
|
368
|
+
justifyContent: "center"
|
|
369
|
+
},
|
|
370
|
+
fullHeightPositioner: { flex: 1 },
|
|
371
|
+
outsidePositioner: {
|
|
372
|
+
alignItems: "center",
|
|
373
|
+
justifyContent: "center",
|
|
374
|
+
minHeight: "100%",
|
|
375
|
+
position: "relative"
|
|
376
|
+
},
|
|
377
|
+
surface: {
|
|
378
|
+
alignSelf: "center",
|
|
379
|
+
position: "relative",
|
|
380
|
+
zIndex: 1
|
|
381
|
+
},
|
|
382
|
+
closeIconContainer: {
|
|
383
|
+
alignItems: "center",
|
|
384
|
+
justifyContent: "center",
|
|
385
|
+
position: "absolute",
|
|
386
|
+
zIndex: 1
|
|
387
|
+
},
|
|
388
|
+
header: { alignItems: "stretch" },
|
|
389
|
+
titleDescriptionWrapper: { minWidth: 0 },
|
|
390
|
+
grow: { flexGrow: 1 }
|
|
391
|
+
});
|
|
392
|
+
//#endregion
|
|
393
|
+
export { Modal };
|
|
394
|
+
|
|
395
|
+
//# sourceMappingURL=Modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.js","names":["Text"],"sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import type { RefObject } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { GestureResponderEvent, NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\nimport { AccessibilityInfo, Platform, ScrollView, StyleSheet, View } from 'react-native';\nimport { GestureHandlerRootView } from 'react-native-gesture-handler';\nimport Animated, {\n Easing,\n interpolate,\n useAnimatedStyle,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\n\nimport { modalStyles } from '../../../generated/styles';\nimport { AndroidBackHandler } from '../AndroidBackHandler';\nimport { Box } from '../Box';\nimport { IconSlot } from '../IconSlot';\nimport { OverlayPortal } from '../internal/Overlay/OverlayPortal';\nimport { AnimatedPressable } from '../Pressable';\nimport { Scrim } from '../Scrim';\nimport { Text } from '../Text';\nimport { ModalActions } from './ModalActions';\nimport { ModalContent } from './ModalContent';\nimport { ModalContext } from './ModalContext';\nimport { ModalDescription } from './ModalDescription';\nimport { ModalTitle } from './ModalTitle';\nimport type { ModalContextValue, ModalProps, ModalRootTokens } from './types';\nimport {\n getEventPagePoint,\n resolveModalDimension,\n separateChildren,\n shouldDismissModalRelease,\n} from './utils';\n\nconst ANIMATION_DURATION_IN = 400;\nconst ANIMATION_DURATION_OUT = 250;\nconst ANIMATION_EASING_IN = Easing.bezier(0.3, 0.4, 0.2, 1);\nconst ANIMATION_EASING_OUT = Easing.bezier(0.6, 0, 0.7, 0.6);\nconst HIDDEN_SCALE = 0.95;\nconst HIDDEN_PROGRESS = 1;\nconst VISIBLE_PROGRESS = 0;\nconst SCROLL_DISMISS_SUPPRESSION_MS = 150;\nconst SCROLL_OFFSET_THRESHOLD = 1;\n\ntype ModalPresenceState = 'closed' | 'closing' | 'open';\n\nfunction usePrefersReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n let isMounted = true;\n\n void AccessibilityInfo.isReduceMotionEnabled().then((isReduceMotionEnabled) => {\n if (isMounted) {\n setPrefersReducedMotion(isReduceMotionEnabled);\n }\n });\n\n const subscription = AccessibilityInfo.addEventListener(\n 'reduceMotionChanged',\n (isReduceMotionEnabled: boolean) => {\n setPrefersReducedMotion(isReduceMotionEnabled);\n },\n );\n\n return () => {\n isMounted = false;\n subscription.remove();\n };\n }, []);\n\n return prefersReducedMotion;\n}\n\nconst Modal = memo(function Modal({\n children,\n open,\n onClose,\n onOpen,\n portal = true,\n includeScrim,\n dismissible = true,\n hideDismissButton = false,\n reduceMotion = false,\n closeIcon = 'Cross',\n closeAriaLabel = 'Close',\n closeAccessibilityLabel,\n maxWidth = 'auto',\n maxHeight = 'auto',\n fullWidth = false,\n fullHeight = false,\n title: titleProp,\n description: descriptionProp,\n content: contentProp,\n actions: actionsProp,\n scrollBehavior = 'outside',\n useFullWindowOverlay = true,\n blurTarget,\n style,\n ref,\n onLayout,\n ...viewProps\n}: ModalProps) {\n modalStyles.useVariants({});\n\n const surfaceRef = useRef<View | null>(null);\n const prevOpen = useRef(open);\n const progress = useSharedValue(HIDDEN_PROGRESS);\n const closePressProgress = useSharedValue(0);\n const presenceState = useRef<ModalPresenceState>(open ? 'open' : 'closed');\n const didModalScrollDuringGesture = useRef(false);\n const isModalScrollInteracting = useRef(false);\n const modalScrollDismissTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n const modalScrollStartOffset = useRef<{ x: number; y: number } | null>(null);\n const [, forcePresenceRender] = useState(0);\n const prefersReducedMotion = usePrefersReducedMotion();\n const reducedMotion = reduceMotion || prefersReducedMotion;\n const safeAreaInsets = useSafeAreaInsets();\n\n if (open) {\n presenceState.current = 'open';\n } else if (presenceState.current === 'open') {\n presenceState.current = 'closing';\n }\n\n const isRendered = open || presenceState.current === 'closing';\n\n const {\n title: modalTitle,\n description: modalDescription,\n content: modalContent,\n actions: modalActions,\n } = separateChildren(children);\n\n const hasTitleOrDescription = !!(modalTitle || titleProp || modalDescription || descriptionProp);\n const shouldRenderHeader = !hideDismissButton || hasTitleOrDescription;\n const hasContent = !!(modalContent || contentProp);\n const shouldRenderScrim = includeScrim ?? true;\n const closeLabel = closeAccessibilityLabel ?? closeAriaLabel;\n const durationIn = reducedMotion ? 0 : ANIMATION_DURATION_IN;\n const durationOut = reducedMotion ? 0 : ANIMATION_DURATION_OUT;\n\n useEffect(() => {\n if (open && !prevOpen.current) {\n onOpen?.();\n }\n prevOpen.current = open;\n }, [open, onOpen]);\n\n useEffect(() => {\n if (open) {\n progress.value = HIDDEN_PROGRESS;\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n progress.value = withTiming(HIDDEN_PROGRESS, {\n duration: durationOut,\n easing: ANIMATION_EASING_OUT,\n });\n\n const timeout = setTimeout(() => {\n if (presenceState.current === 'closing') {\n presenceState.current = 'closed';\n forcePresenceRender((revision) => revision + 1);\n }\n }, durationOut);\n\n return () => clearTimeout(timeout);\n }, [durationOut, isRendered, open, progress]);\n\n useEffect(() => {\n if (!open || !isRendered) {\n return;\n }\n\n if (durationIn === 0) {\n progress.value = VISIBLE_PROGRESS;\n return;\n }\n\n const animationFrame = requestAnimationFrame(() => {\n progress.value = withTiming(VISIBLE_PROGRESS, {\n duration: durationIn,\n easing: ANIMATION_EASING_IN,\n });\n });\n\n return () => cancelAnimationFrame(animationFrame);\n }, [durationIn, isRendered, open, progress]);\n\n const handleDismiss = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const clearModalScrollDismissTimeout = useCallback(() => {\n if (modalScrollDismissTimeout.current) {\n clearTimeout(modalScrollDismissTimeout.current);\n modalScrollDismissTimeout.current = null;\n }\n }, []);\n\n const handleModalScrollInteractionBegin = useCallback(\n (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n clearModalScrollDismissTimeout();\n isModalScrollInteracting.current = true;\n didModalScrollDuringGesture.current = false;\n modalScrollStartOffset.current = event.nativeEvent.contentOffset;\n },\n [clearModalScrollDismissTimeout],\n );\n\n const handleModalScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (!isModalScrollInteracting.current || didModalScrollDuringGesture.current) {\n return;\n }\n\n const startOffset = modalScrollStartOffset.current;\n const currentOffset = event.nativeEvent.contentOffset;\n\n if (!startOffset) {\n return;\n }\n\n const movedX = Math.abs(currentOffset.x - startOffset.x);\n const movedY = Math.abs(currentOffset.y - startOffset.y);\n\n if (movedX > SCROLL_OFFSET_THRESHOLD || movedY > SCROLL_OFFSET_THRESHOLD) {\n didModalScrollDuringGesture.current = true;\n }\n }, []);\n\n const handleModalScrollInteractionEnd = useCallback(() => {\n clearModalScrollDismissTimeout();\n modalScrollDismissTimeout.current = setTimeout(() => {\n isModalScrollInteracting.current = false;\n didModalScrollDuringGesture.current = false;\n modalScrollDismissTimeout.current = null;\n modalScrollStartOffset.current = null;\n }, SCROLL_DISMISS_SUPPRESSION_MS);\n }, [clearModalScrollDismissTimeout]);\n\n useEffect(() => clearModalScrollDismissTimeout, [clearModalScrollDismissTimeout]);\n\n const handleScrimRelease = useCallback(\n (absoluteX: number, absoluteY: number) => {\n if (!dismissible) {\n return;\n }\n\n if (!surfaceRef.current?.measureInWindow) {\n return;\n }\n\n surfaceRef.current.measureInWindow((x, y, width, height) => {\n if (shouldDismissModalRelease({ x: absoluteX, y: absoluteY }, { x, y, width, height })) {\n onClose?.();\n }\n });\n },\n [dismissible, onClose],\n );\n\n const handleOverlayTouchEndCapture = useCallback(\n (event: GestureResponderEvent) => {\n if (isModalScrollInteracting.current && didModalScrollDuringGesture.current) {\n return;\n }\n\n const pagePoint = getEventPagePoint(event);\n\n if (!pagePoint) {\n return;\n }\n\n handleScrimRelease(pagePoint.x, pagePoint.y);\n },\n [handleScrimRelease],\n );\n\n const setSurfaceRef = useCallback(\n (node: View | null) => {\n surfaceRef.current = node;\n\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref],\n );\n\n const handleClosePressIn = useCallback(() => {\n closePressProgress.value = withTiming(1, {\n duration: reducedMotion ? 0 : 120,\n });\n }, [closePressProgress, reducedMotion]);\n\n const handleClosePressOut = useCallback(() => {\n closePressProgress.value = withTiming(0, {\n duration: reducedMotion ? 0 : 120,\n });\n }, [closePressProgress, reducedMotion]);\n\n const animatedSurfaceStyle = useAnimatedStyle(() => ({\n opacity: interpolate(progress.value, [VISIBLE_PROGRESS, HIDDEN_PROGRESS], [1, 0], 'clamp'),\n transform: [\n {\n scale: interpolate(\n progress.value,\n [VISIBLE_PROGRESS, HIDDEN_PROGRESS],\n [1, HIDDEN_SCALE],\n 'clamp',\n ),\n },\n ],\n }));\n\n const animatedCloseIconContainerStyle = useAnimatedStyle(() => ({\n backgroundColor: `rgba(29, 34, 40, ${interpolate(\n closePressProgress.value,\n [0, 1],\n [0, 0.15],\n 'clamp',\n ).toFixed(3)})`,\n }));\n\n const modalContextValue = useMemo<ModalContextValue>(\n () => ({\n scrollBehavior,\n hasContent,\n onScroll: handleModalScroll,\n onScrollInteractionBegin: handleModalScrollInteractionBegin,\n onScrollInteractionEnd: handleModalScrollInteractionEnd,\n shouldRenderHeader,\n }),\n [\n handleModalScroll,\n handleModalScrollInteractionBegin,\n handleModalScrollInteractionEnd,\n hasContent,\n scrollBehavior,\n shouldRenderHeader,\n ],\n );\n\n if (!isRendered) {\n return null;\n }\n\n const rootTokens = StyleSheet.flatten(modalStyles.root) as ModalRootTokens;\n const scrimTokens = StyleSheet.flatten(modalStyles.scrim) as { padding?: number };\n const gutter = scrimTokens.padding ?? 0;\n const blurIntensity = rootTokens.backgroundBlurRadius ?? 0;\n const showBlurBox = blurIntensity > 0 && (Platform.OS === 'ios' || blurTarget != null);\n const rootBackgroundColor = showBlurBox\n ? 'transparent'\n : blurIntensity > 0\n ? (rootTokens.backgroundBlurColor ?? rootTokens.backgroundColor)\n : rootTokens.backgroundColor;\n const rootBorderRadius = rootTokens.borderRadius ?? 0;\n const rootMaxHeight = scrollBehavior === 'inside' ? resolveModalDimension(maxHeight) : undefined;\n const shouldFillHeight = fullHeight && scrollBehavior === 'inside' && rootMaxHeight !== undefined;\n const headerSpacingBottom = hasContent ? (modalStyles.root.paddingVertical ?? 0) : 0;\n const closeIconSize = modalStyles.closeIcon.fontSize ?? 0;\n const closeIconPadding = modalStyles.closeIconContainer.padding ?? 0;\n const closeIconContainerSize = closeIconSize + closeIconPadding * 2;\n const closeIconOffset = closeIconContainerSize / 2;\n const closeIconTop = modalStyles.root.paddingVertical ?? 0;\n const closeIconRight = modalStyles.spacingHorizontal.paddingHorizontal ?? 0;\n\n const surface = (\n <Animated.View\n ref={setSurfaceRef}\n accessibilityViewIsModal\n importantForAccessibility=\"yes\"\n {...viewProps}\n onLayout={onLayout}\n style={[\n modalStyles.root,\n internalStyles.surface,\n {\n backgroundColor: rootBackgroundColor,\n maxHeight: rootMaxHeight,\n maxWidth: resolveModalDimension(maxWidth),\n height: shouldFillHeight ? rootMaxHeight : undefined,\n width: fullWidth ? '100%' : undefined,\n borderRadius: rootBorderRadius,\n overflow: showBlurBox ? 'hidden' : undefined,\n },\n animatedSurfaceStyle,\n style,\n ]}\n >\n {showBlurBox && (\n <>\n <Box style={StyleSheet.absoluteFill} blur={blurIntensity} blurTarget={blurTarget} />\n <View\n pointerEvents=\"none\"\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: rootTokens.backgroundBlurColor,\n borderRadius: rootBorderRadius,\n },\n ]}\n />\n </>\n )}\n\n <ModalContext.Provider value={modalContextValue}>\n {!hideDismissButton && closeIcon !== false && (\n <AnimatedPressable\n accessibilityLabel={closeLabel}\n accessibilityRole=\"button\"\n hitSlop={12}\n onPress={onClose}\n onPressIn={handleClosePressIn}\n onPressOut={handleClosePressOut}\n style={[\n modalStyles.closeIconContainer,\n internalStyles.closeIconContainer,\n {\n borderRadius: closeIconContainerSize,\n right: closeIconRight,\n top: closeIconTop,\n transform: [{ translateX: closeIconOffset }, { translateY: -closeIconOffset }],\n },\n animatedCloseIconContainerStyle,\n ]}\n >\n <IconSlot\n icon={closeIcon}\n variant=\"outline\"\n size={modalStyles.closeIcon.iconSizeToken ?? 'md'}\n style={modalStyles.closeIcon}\n accessibilityElementsHidden\n importantForAccessibility=\"no\"\n />\n </AnimatedPressable>\n )}\n {shouldRenderHeader && (\n <View\n style={[\n modalStyles.spacingHorizontal,\n internalStyles.header,\n { marginBottom: headerSpacingBottom },\n ]}\n >\n {hasTitleOrDescription && (\n <View\n style={[\n internalStyles.titleDescriptionWrapper,\n { gap: modalStyles.titleDescriptionWrapper.gap },\n ]}\n >\n {modalTitle || (titleProp ? <ModalTitle>{titleProp}</ModalTitle> : null)}\n {modalDescription ||\n (descriptionProp ? <ModalDescription>{descriptionProp}</ModalDescription> : null)}\n </View>\n )}\n </View>\n )}\n\n {modalContent ||\n (contentProp ? (\n <ModalContent>\n {typeof contentProp === 'string' || typeof contentProp === 'number' ? (\n <Text color=\"secondary\" variant=\"ui1\">\n {contentProp}\n </Text>\n ) : (\n contentProp\n )}\n </ModalContent>\n ) : (\n <View style={internalStyles.grow} />\n ))}\n\n {modalActions || (actionsProp ? <ModalActions>{actionsProp}</ModalActions> : null)}\n </ModalContext.Provider>\n </Animated.View>\n );\n\n const positionerInsetStyle = {\n paddingTop: safeAreaInsets.top + gutter,\n paddingRight: safeAreaInsets.right + gutter,\n paddingBottom: safeAreaInsets.bottom + gutter,\n paddingLeft: safeAreaInsets.left + gutter,\n };\n\n const positionerStyle = [\n internalStyles.positioner,\n shouldFillHeight && internalStyles.fullHeightPositioner,\n positionerInsetStyle,\n ];\n\n const outsidePositionerStyle = [internalStyles.outsidePositioner, positionerInsetStyle];\n\n const positionedSurface = (\n <View style={positionerStyle} testID=\"uds-modal-positioner\">\n {surface}\n </View>\n );\n\n const overlay = (\n <GestureHandlerRootView style={StyleSheet.absoluteFill}>\n <View\n onTouchEndCapture={dismissible ? handleOverlayTouchEndCapture : undefined}\n pointerEvents=\"auto\"\n style={StyleSheet.absoluteFill}\n testID=\"uds-modal-overlay\"\n >\n <AndroidBackHandler isOpen={open} dismissible={dismissible} onDismiss={handleDismiss} />\n {shouldRenderScrim && (\n <Scrim\n translateY={progress}\n openTranslateY={VISIBLE_PROGRESS}\n closedTranslateY={HIDDEN_PROGRESS}\n dismissible={false}\n onDismiss={handleDismiss}\n blurTarget={blurTarget as RefObject<View | null> | undefined}\n />\n )}\n {scrollBehavior === 'outside' ? (\n <ScrollView\n alwaysBounceVertical={false}\n bounces={false}\n keyboardShouldPersistTaps=\"handled\"\n onMomentumScrollEnd={handleModalScrollInteractionEnd}\n onScroll={handleModalScroll}\n onScrollBeginDrag={handleModalScrollInteractionBegin}\n onScrollEndDrag={handleModalScrollInteractionEnd}\n overScrollMode=\"never\"\n scrollEventThrottle={16}\n contentContainerStyle={outsidePositionerStyle}\n style={StyleSheet.absoluteFill}\n >\n {surface}\n </ScrollView>\n ) : (\n positionedSurface\n )}\n </View>\n </GestureHandlerRootView>\n );\n\n if (!portal) {\n return overlay;\n }\n\n return <OverlayPortal useFullWindowOverlay={useFullWindowOverlay}>{overlay}</OverlayPortal>;\n});\n\nModal.displayName = 'Modal';\n\nconst internalStyles = StyleSheet.create({\n positioner: {\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'center',\n },\n fullHeightPositioner: {\n flex: 1,\n },\n outsidePositioner: {\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '100%',\n position: 'relative',\n },\n surface: {\n alignSelf: 'center',\n position: 'relative',\n zIndex: 1,\n },\n closeIconContainer: {\n alignItems: 'center',\n justifyContent: 'center',\n position: 'absolute',\n zIndex: 1,\n },\n header: {\n alignItems: 'stretch',\n },\n titleDescriptionWrapper: {\n minWidth: 0,\n },\n grow: {\n flexGrow: 1,\n },\n});\n\nexport { Modal };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
require("../../_virtual/_rolldown/runtime.cjs");
|
|
4
|
+
const require_components_Modal_ModalContext = require("./ModalContext.cjs");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
let react_native = require("react-native");
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let generated_styles = require("../../../generated/styles");
|
|
9
|
+
//#region src/components/Modal/ModalActions.tsx
|
|
10
|
+
const ModalActions = (0, react.memo)(function ModalActions({ children, startContent, style, ref, ...viewProps }) {
|
|
11
|
+
const { hasContent, shouldRenderHeader } = require_components_Modal_ModalContext.useInternalModalContext();
|
|
12
|
+
generated_styles.modalStyles.useVariants({});
|
|
13
|
+
const spacingTop = !hasContent && shouldRenderHeader ? 0 : generated_styles.modalStyles.root.paddingVertical ?? 0;
|
|
14
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
|
|
15
|
+
ref,
|
|
16
|
+
...viewProps,
|
|
17
|
+
style: [
|
|
18
|
+
generated_styles.modalStyles.spacingHorizontal,
|
|
19
|
+
internalStyles.root,
|
|
20
|
+
{ paddingTop: spacingTop },
|
|
21
|
+
style
|
|
22
|
+
],
|
|
23
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
24
|
+
style: [internalStyles.actionsInner, { gap: generated_styles.modalStyles.actions.gap }],
|
|
25
|
+
children
|
|
26
|
+
}), startContent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
27
|
+
style: internalStyles.startContent,
|
|
28
|
+
children: startContent
|
|
29
|
+
})]
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
ModalActions.displayName = "ModalActions";
|
|
33
|
+
ModalActions.__modalSlot = "actions";
|
|
34
|
+
const internalStyles = react_native.StyleSheet.create({
|
|
35
|
+
root: {
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
flexDirection: "row-reverse",
|
|
38
|
+
justifyContent: "space-between"
|
|
39
|
+
},
|
|
40
|
+
actionsInner: {
|
|
41
|
+
alignItems: "center",
|
|
42
|
+
flexDirection: "row-reverse"
|
|
43
|
+
},
|
|
44
|
+
startContent: { alignItems: "center" }
|
|
45
|
+
});
|
|
46
|
+
//#endregion
|
|
47
|
+
exports.ModalActions = ModalActions;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
import { ModalActionsProps } from "./types.cjs";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Modal/ModalActions.d.ts
|
|
6
|
+
declare const ModalActions: _$react.NamedExoticComponent<ModalActionsProps>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ModalActions, type ModalActionsProps };
|
|
9
|
+
//# sourceMappingURL=ModalActions.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalActions.d.cts","names":[],"sources":["../../../src/components/Modal/ModalActions.tsx"],"mappings":";;;;;cAOM,YAAA,EAAY,OAAA,CAAA,oBAAA,CAAA,iBAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
import { ModalActionsProps } from "./types.js";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Modal/ModalActions.d.ts
|
|
6
|
+
declare const ModalActions: _$react.NamedExoticComponent<ModalActionsProps>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ModalActions, type ModalActionsProps };
|
|
9
|
+
//# sourceMappingURL=ModalActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalActions.d.ts","names":[],"sources":["../../../src/components/Modal/ModalActions.tsx"],"mappings":";;;;;cAOM,YAAA,EAAY,OAAA,CAAA,oBAAA,CAAA,iBAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
import { useInternalModalContext } from "./ModalContext.js";
|
|
3
|
+
import { memo } from "react";
|
|
4
|
+
import { StyleSheet, View } from "react-native";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { modalStyles } from "../../../generated/styles";
|
|
7
|
+
//#region src/components/Modal/ModalActions.tsx
|
|
8
|
+
const ModalActions = memo(function ModalActions({ children, startContent, style, ref, ...viewProps }) {
|
|
9
|
+
const { hasContent, shouldRenderHeader } = useInternalModalContext();
|
|
10
|
+
modalStyles.useVariants({});
|
|
11
|
+
const spacingTop = !hasContent && shouldRenderHeader ? 0 : modalStyles.root.paddingVertical ?? 0;
|
|
12
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
13
|
+
ref,
|
|
14
|
+
...viewProps,
|
|
15
|
+
style: [
|
|
16
|
+
modalStyles.spacingHorizontal,
|
|
17
|
+
internalStyles.root,
|
|
18
|
+
{ paddingTop: spacingTop },
|
|
19
|
+
style
|
|
20
|
+
],
|
|
21
|
+
children: [/* @__PURE__ */ jsx(View, {
|
|
22
|
+
style: [internalStyles.actionsInner, { gap: modalStyles.actions.gap }],
|
|
23
|
+
children
|
|
24
|
+
}), startContent && /* @__PURE__ */ jsx(View, {
|
|
25
|
+
style: internalStyles.startContent,
|
|
26
|
+
children: startContent
|
|
27
|
+
})]
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
ModalActions.displayName = "ModalActions";
|
|
31
|
+
ModalActions.__modalSlot = "actions";
|
|
32
|
+
const internalStyles = StyleSheet.create({
|
|
33
|
+
root: {
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
flexDirection: "row-reverse",
|
|
36
|
+
justifyContent: "space-between"
|
|
37
|
+
},
|
|
38
|
+
actionsInner: {
|
|
39
|
+
alignItems: "center",
|
|
40
|
+
flexDirection: "row-reverse"
|
|
41
|
+
},
|
|
42
|
+
startContent: { alignItems: "center" }
|
|
43
|
+
});
|
|
44
|
+
//#endregion
|
|
45
|
+
export { ModalActions };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=ModalActions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalActions.js","names":[],"sources":["../../../src/components/Modal/ModalActions.tsx"],"sourcesContent":["import { memo } from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport { modalStyles } from '../../../generated/styles';\nimport { useInternalModalContext } from './ModalContext';\nimport type { ModalActionsProps, ModalSlotComponent } from './types';\n\nconst ModalActions = memo(function ModalActions({\n children,\n startContent,\n style,\n ref,\n ...viewProps\n}: ModalActionsProps) {\n const { hasContent, shouldRenderHeader } = useInternalModalContext();\n\n modalStyles.useVariants({});\n const spacingTop =\n !hasContent && shouldRenderHeader ? 0 : (modalStyles.root.paddingVertical ?? 0);\n\n return (\n <View\n ref={ref}\n {...viewProps}\n style={[\n modalStyles.spacingHorizontal,\n internalStyles.root,\n { paddingTop: spacingTop },\n style,\n ]}\n >\n <View style={[internalStyles.actionsInner, { gap: modalStyles.actions.gap }]}>\n {children}\n </View>\n {startContent && <View style={internalStyles.startContent}>{startContent}</View>}\n </View>\n );\n});\n\nModalActions.displayName = 'ModalActions';\n(ModalActions as ModalSlotComponent).__modalSlot = 'actions';\n\nconst internalStyles = StyleSheet.create({\n root: {\n alignItems: 'center',\n flexDirection: 'row-reverse',\n justifyContent: 'space-between',\n },\n actionsInner: {\n alignItems: 'center',\n flexDirection: 'row-reverse',\n },\n startContent: {\n alignItems: 'center',\n },\n});\n\nexport { ModalActions, type ModalActionsProps };\n"],"mappings":";;;;;;;AAOA,MAAM,eAAe,KAAK,SAAS,aAAa,EAC9C,UACA,cACA,OACA,KACA,GAAG,aACiB;CACpB,MAAM,EAAE,YAAY,uBAAuB,yBAAyB;CAEpE,YAAY,YAAY,EAAE,CAAC;CAC3B,MAAM,aACJ,CAAC,cAAc,qBAAqB,IAAK,YAAY,KAAK,mBAAmB;CAE/E,OACE,qBAAC,MAAD;EACO;EACL,GAAI;EACJ,OAAO;GACL,YAAY;GACZ,eAAe;GACf,EAAE,YAAY,YAAY;GAC1B;GACD;YARH,CAUE,oBAAC,MAAD;GAAM,OAAO,CAAC,eAAe,cAAc,EAAE,KAAK,YAAY,QAAQ,KAAK,CAAC;GACzE;GACI,CAAA,EACN,gBAAgB,oBAAC,MAAD;GAAM,OAAO,eAAe;aAAe;GAAoB,CAAA,CAC3E;;EAET;AAEF,aAAa,cAAc;AAC3B,aAAqC,cAAc;AAEnD,MAAM,iBAAiB,WAAW,OAAO;CACvC,MAAM;EACJ,YAAY;EACZ,eAAe;EACf,gBAAgB;EACjB;CACD,cAAc;EACZ,YAAY;EACZ,eAAe;EAChB;CACD,cAAc,EACZ,YAAY,UACb;CACF,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
require("../../_virtual/_rolldown/runtime.cjs");
|
|
4
|
+
const require_components_Modal_ModalContext = require("./ModalContext.cjs");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
let react_native = require("react-native");
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let generated_styles = require("../../../generated/styles");
|
|
9
|
+
//#region src/components/Modal/ModalContent.tsx
|
|
10
|
+
const ModalContent = (0, react.memo)(function ModalContent({ children, contentContainerStyle, style, ref, ...viewProps }) {
|
|
11
|
+
const { onScroll, onScrollInteractionBegin, onScrollInteractionEnd, scrollBehavior } = require_components_Modal_ModalContext.useInternalModalContext();
|
|
12
|
+
generated_styles.modalStyles.useVariants({});
|
|
13
|
+
if (scrollBehavior === "inside") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
|
|
14
|
+
ref,
|
|
15
|
+
disableScrollViewPanResponder: true,
|
|
16
|
+
keyboardShouldPersistTaps: "handled",
|
|
17
|
+
...viewProps,
|
|
18
|
+
contentContainerStyle: [generated_styles.modalStyles.spacingHorizontal, contentContainerStyle],
|
|
19
|
+
onMomentumScrollEnd: onScrollInteractionEnd,
|
|
20
|
+
onScroll,
|
|
21
|
+
onScrollBeginDrag: onScrollInteractionBegin,
|
|
22
|
+
onScrollEndDrag: onScrollInteractionEnd,
|
|
23
|
+
scrollEventThrottle: 16,
|
|
24
|
+
style: [styles.insideContent, style],
|
|
25
|
+
children
|
|
26
|
+
});
|
|
27
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
28
|
+
ref,
|
|
29
|
+
...viewProps,
|
|
30
|
+
style: [generated_styles.modalStyles.spacingHorizontal, style],
|
|
31
|
+
children
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
ModalContent.displayName = "ModalContent";
|
|
35
|
+
ModalContent.__modalSlot = "content";
|
|
36
|
+
const styles = react_native.StyleSheet.create({ insideContent: {
|
|
37
|
+
flexGrow: 1,
|
|
38
|
+
flexShrink: 1
|
|
39
|
+
} });
|
|
40
|
+
//#endregion
|
|
41
|
+
exports.ModalContent = ModalContent;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
import { ModalContentProps } from "./types.cjs";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Modal/ModalContent.d.ts
|
|
6
|
+
declare const ModalContent: _$react.NamedExoticComponent<ModalContentProps>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ModalContent, type ModalContentProps };
|
|
9
|
+
//# sourceMappingURL=ModalContent.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalContent.d.cts","names":[],"sources":["../../../src/components/Modal/ModalContent.tsx"],"mappings":";;;;;cASM,YAAA,EAAY,OAAA,CAAA,oBAAA,CAAA,iBAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
import { ModalContentProps } from "./types.js";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Modal/ModalContent.d.ts
|
|
6
|
+
declare const ModalContent: _$react.NamedExoticComponent<ModalContentProps>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ModalContent, type ModalContentProps };
|
|
9
|
+
//# sourceMappingURL=ModalContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalContent.d.ts","names":[],"sources":["../../../src/components/Modal/ModalContent.tsx"],"mappings":";;;;;cASM,YAAA,EAAY,OAAA,CAAA,oBAAA,CAAA,iBAAA"}
|