@mustmove/overlay-kit-rn 1.0.21 → 1.0.22
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/index.js +27 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ __export(index_exports, {
|
|
|
69
69
|
module.exports = __toCommonJS(index_exports);
|
|
70
70
|
|
|
71
71
|
// src/context/provider/index.tsx
|
|
72
|
-
var
|
|
72
|
+
var import_react7 = require("react");
|
|
73
73
|
|
|
74
74
|
// src/context/provider/content-overlay-controller.tsx
|
|
75
75
|
var import_react = require("react");
|
|
@@ -460,6 +460,9 @@ var styles2 = import_react_native2.StyleSheet.create({
|
|
|
460
460
|
}
|
|
461
461
|
});
|
|
462
462
|
|
|
463
|
+
// src/event.ts
|
|
464
|
+
var import_react5 = __toESM(require("react"));
|
|
465
|
+
|
|
463
466
|
// src/utils/create-use-external-events.ts
|
|
464
467
|
var import_react4 = require("react");
|
|
465
468
|
|
|
@@ -557,8 +560,19 @@ function createOverlay(overlayId) {
|
|
|
557
560
|
const overlayType = (_b = options == null ? void 0 : options.overlayType) != null ? _b : "overlay";
|
|
558
561
|
const dispatchOpenEvent = createEvent("open");
|
|
559
562
|
const _c = options || {}, { overlayId: _, overlayType: __ } = _c, restOptions = __objRest(_c, ["overlayId", "overlayType"]);
|
|
563
|
+
let finalController;
|
|
564
|
+
if (import_react5.default.isValidElement(controller)) {
|
|
565
|
+
finalController = (props) => {
|
|
566
|
+
return import_react5.default.cloneElement(controller, __spreadProps(__spreadValues(__spreadValues({}, controller.props || {}), props), {
|
|
567
|
+
close: props.close,
|
|
568
|
+
unmount: props.unmount
|
|
569
|
+
}));
|
|
570
|
+
};
|
|
571
|
+
} else {
|
|
572
|
+
finalController = controller;
|
|
573
|
+
}
|
|
560
574
|
dispatchOpenEvent({
|
|
561
|
-
controller,
|
|
575
|
+
controller: finalController,
|
|
562
576
|
overlayId: overlayId2,
|
|
563
577
|
componentKey,
|
|
564
578
|
overlayType,
|
|
@@ -568,7 +582,7 @@ function createOverlay(overlayId) {
|
|
|
568
582
|
};
|
|
569
583
|
const openAsync = async (controller, options) => {
|
|
570
584
|
return new Promise((resolve) => {
|
|
571
|
-
const wrappedController = (overlayProps
|
|
585
|
+
const wrappedController = (overlayProps) => {
|
|
572
586
|
const close2 = (param) => {
|
|
573
587
|
resolve(param);
|
|
574
588
|
overlayProps.close();
|
|
@@ -599,13 +613,13 @@ function createOverlay(overlayId) {
|
|
|
599
613
|
}
|
|
600
614
|
|
|
601
615
|
// src/utils/create-safe-context.ts
|
|
602
|
-
var
|
|
616
|
+
var import_react6 = require("react");
|
|
603
617
|
var NullSymbol = Symbol("Null");
|
|
604
618
|
function createSafeContext(displayName) {
|
|
605
|
-
const Context = (0,
|
|
619
|
+
const Context = (0, import_react6.createContext)(NullSymbol);
|
|
606
620
|
Context.displayName = displayName != null ? displayName : "SafeContext";
|
|
607
621
|
function useSafeContext() {
|
|
608
|
-
const context = (0,
|
|
622
|
+
const context = (0, import_react6.useContext)(Context);
|
|
609
623
|
if (context === NullSymbol) {
|
|
610
624
|
const error = new Error(`[${Context.displayName}]: Provider not found.`);
|
|
611
625
|
error.name = "[Error] Context";
|
|
@@ -744,12 +758,12 @@ function createOverlayProvider() {
|
|
|
744
758
|
const _a = createOverlay(overlayId), { useOverlayEvent } = _a, overlay2 = __objRest(_a, ["useOverlayEvent"]);
|
|
745
759
|
const { OverlayContextProvider, useCurrentOverlay: useCurrentOverlay2, useOverlayData: useOverlayData2 } = createOverlaySafeContext();
|
|
746
760
|
function OverlayProvider2({ children }) {
|
|
747
|
-
const [overlayState, overlayDispatch] = (0,
|
|
761
|
+
const [overlayState, overlayDispatch] = (0, import_react7.useReducer)(overlayReducer, {
|
|
748
762
|
current: null,
|
|
749
763
|
overlayOrderList: [],
|
|
750
764
|
overlayData: {}
|
|
751
765
|
});
|
|
752
|
-
const overlayOpen = (0,
|
|
766
|
+
const overlayOpen = (0, import_react7.useCallback)(
|
|
753
767
|
({
|
|
754
768
|
controller,
|
|
755
769
|
overlayId: overlayId2,
|
|
@@ -772,16 +786,16 @@ function createOverlayProvider() {
|
|
|
772
786
|
},
|
|
773
787
|
[]
|
|
774
788
|
);
|
|
775
|
-
const close = (0,
|
|
789
|
+
const close = (0, import_react7.useCallback)((overlayId2) => {
|
|
776
790
|
overlayDispatch({ type: "CLOSE", overlayId: overlayId2 });
|
|
777
791
|
}, []);
|
|
778
|
-
const unmount = (0,
|
|
792
|
+
const unmount = (0, import_react7.useCallback)((overlayId2) => {
|
|
779
793
|
overlayDispatch({ type: "REMOVE", overlayId: overlayId2 });
|
|
780
794
|
}, []);
|
|
781
|
-
const closeAll = (0,
|
|
795
|
+
const closeAll = (0, import_react7.useCallback)(() => {
|
|
782
796
|
overlayDispatch({ type: "CLOSE_ALL" });
|
|
783
797
|
}, []);
|
|
784
|
-
const unmountAll = (0,
|
|
798
|
+
const unmountAll = (0, import_react7.useCallback)(() => {
|
|
785
799
|
overlayDispatch({ type: "REMOVE_ALL" });
|
|
786
800
|
}, []);
|
|
787
801
|
useOverlayEvent({
|
|
@@ -791,7 +805,7 @@ function createOverlayProvider() {
|
|
|
791
805
|
closeAll,
|
|
792
806
|
unmountAll
|
|
793
807
|
});
|
|
794
|
-
(0,
|
|
808
|
+
(0, import_react7.useEffect)(() => {
|
|
795
809
|
return () => {
|
|
796
810
|
overlayDispatch({ type: "REMOVE_ALL" });
|
|
797
811
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/context/provider/index.tsx","../src/context/provider/content-overlay-controller.tsx","../src/context/provider/bottom-sheet-controller.tsx","../src/context/provider/modal-controller.tsx","../src/utils/create-use-external-events.ts","../src/utils/emitter.ts","../src/utils/random-id.ts","../src/event.ts","../src/utils/create-safe-context.ts","../src/context/context.ts","../src/context/reducer.ts","../src/utils/create-overlay-context.tsx"],"sourcesContent":["export * from \"./utils\";\nexport { overlay, OverlayProvider, useCurrentOverlay, useOverlayData } from \"./utils/create-overlay-context\";\nexport type {\n OverlayControllerComponent,\n OverlayAsyncControllerComponent,\n} from \"./context/provider/content-overlay-controller\";\nexport type { BottomSheetControllerComponent } from \"./context/provider/bottom-sheet-controller\";\nexport type { ModalControllerComponent } from \"./context/provider/modal-controller\";\n","import {\n useCallback,\n useEffect,\n useReducer,\n type PropsWithChildren,\n} from \"react\";\nimport { View } from \"react-native\";\nimport { ContentOverlayController } from \"./content-overlay-controller\";\nimport { ContentBottomSheetController } from \"./bottom-sheet-controller\";\nimport { ContentModalController } from \"./modal-controller\";\nimport { type OverlayEvent, createOverlay } from \"../../event\";\nimport { randomId } from \"../../utils/random-id\";\nimport { createOverlaySafeContext } from \"../context\";\nimport { overlayReducer } from \"../reducer\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport { BottomSheetModalProvider } from \"@gorhom/bottom-sheet\";\n\nexport function createOverlayProvider() {\n const overlayId = randomId();\n const { useOverlayEvent, ...overlay } = createOverlay(overlayId);\n\n const { OverlayContextProvider, useCurrentOverlay, useOverlayData } =\n createOverlaySafeContext();\n\n function OverlayProvider({ children }: PropsWithChildren) {\n const [overlayState, overlayDispatch] = useReducer(overlayReducer, {\n current: null,\n overlayOrderList: [],\n overlayData: {},\n });\n\n // Overlay 이벤트 핸들러들\n const overlayOpen: OverlayEvent[\"open\"] = useCallback(\n ({\n controller,\n overlayId,\n componentKey,\n overlayType = \"overlay\",\n options,\n }) => {\n overlayDispatch({\n type: \"ADD\",\n overlay: {\n id: overlayId,\n componentKey,\n isOpen: true,\n isMounted: true,\n controller: controller,\n overlayType,\n options,\n },\n });\n },\n []\n );\n\n const close = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, []);\n\n const unmount = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"REMOVE\", overlayId });\n }, []);\n\n const closeAll = useCallback(() => {\n overlayDispatch({ type: \"CLOSE_ALL\" });\n }, []);\n\n const unmountAll = useCallback(() => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n }, []);\n\n // 이벤트 리스너 등록\n useOverlayEvent({\n open: overlayOpen,\n close,\n unmount,\n closeAll,\n unmountAll,\n });\n\n useEffect(() => {\n return () => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n };\n }, []);\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <BottomSheetModalProvider>\n <OverlayContextProvider value={overlayState}>\n {children}\n\n {overlayState.overlayOrderList.map((item) => {\n const overlayItem = overlayState.overlayData[item];\n const {\n id: currentOverlayId,\n componentKey,\n isOpen,\n controller: Controller,\n overlayType,\n options,\n } = overlayItem;\n\n // 타입에 따라 다른 컨트롤러 렌더링\n if (overlayType === \"bottomSheet\") {\n return (\n <ContentBottomSheetController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else if (overlayType === \"modal\") {\n // 모달의 경우 현재 활성화된 모달만 표시\n const isCurrentModal =\n overlayState.current === currentOverlayId;\n const shouldShow = isOpen && isCurrentModal;\n\n return (\n <ContentModalController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else {\n // 기존 overlay (backward compatibility)\n return (\n <ContentOverlayController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n />\n );\n }\n })}\n </OverlayContextProvider>\n </BottomSheetModalProvider>\n </GestureHandlerRootView>\n );\n }\n\n return {\n overlay,\n OverlayProvider,\n useCurrentOverlay,\n useOverlayData,\n };\n}\n","import React, { type FC, memo, useEffect, type Dispatch } from \"react\";\nimport { Modal } from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype OverlayControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n};\n\ntype OverlayAsyncControllerProps<T> = Omit<OverlayControllerProps, \"close\"> & {\n close: (param: T) => void;\n};\n\nexport type OverlayControllerComponent = FC<OverlayControllerProps>;\nexport type OverlayAsyncControllerComponent<T> = FC<\n OverlayAsyncControllerProps<T>\n>;\n\ntype ContentOverlayControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: OverlayControllerComponent;\n};\n\nexport const ContentOverlayController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n }: ContentOverlayControllerProps) => {\n useEffect(() => {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n }, [overlayDispatch, overlayId]);\n\n return (\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n />\n );\n }\n);\n","import React, {\n type FC,\n memo,\n useEffect,\n useRef,\n type Dispatch,\n useCallback,\n useState,\n} from \"react\";\nimport BottomSheet, {\n BottomSheetModal,\n BottomSheetView,\n BottomSheetFlatList,\n BottomSheetScrollView,\n BottomSheetBackdrop,\n BottomSheetModalProvider,\n BottomSheetTextInput,\n} from \"@gorhom/bottom-sheet\";\nimport {\n StyleProp,\n ViewStyle,\n ListRenderItem,\n View,\n StyleSheet,\n Platform,\n Keyboard,\n} from \"react-native\";\nimport { useReducedMotion } from \"react-native-reanimated\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype BottomSheetControllerProps<T = any> = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Enhanced features\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n // FlatList support\n isFlatList?: boolean;\n data?: ArrayLike<T> | null | undefined;\n renderItem?: ListRenderItem<T> | null | undefined;\n keyExtractor?: ((item: T, index: number) => string) | undefined;\n contentContainerStyle?: StyleProp<ViewStyle> | undefined;\n ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;\n flatListHeader?: React.ReactNode;\n flatListFooter?: React.ReactNode;\n // Backdrop\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n onBackdropPress?: () => void;\n // Dynamic sizing\n enableDynamicSizing?: boolean;\n // Scrolling\n enableScrolling?: boolean;\n // Styling\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n // Loading & empty state\n isLoading?: boolean;\n emptyText?: string;\n extraData?: any;\n // Keyboard height (Android)\n keyboardHeight?: number;\n};\n\nexport type BottomSheetControllerComponent<T = any> = FC<\n BottomSheetControllerProps<T>\n>;\n\ntype ContentBottomSheetControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: BottomSheetControllerComponent;\n options?: {\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n enableDynamicSizing?: boolean;\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n [key: string]: any;\n };\n};\n\nexport const ContentBottomSheetController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentBottomSheetControllerProps) => {\n const bottomSheetRef = useRef<BottomSheet>(null);\n const reducedMotion = useReducedMotion();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n // --- Android keyboard handling defaults ---\n // On Android, the sheet won't move with the keyboard unless:\n // 1) Activity windowSoftInputMode = \"adjustResize\"\n // 2) bottom-sheet uses keyboardBehavior=\"extend\"\n // 3) Text inputs inside sheet use BottomSheetTextInput\n\n const {\n snapPoints,\n enablePanDownToClose = true,\n enableBackdrop = true,\n backdropOpacity = 0.5,\n enableDynamicSizing = true,\n backgroundStyle = {},\n handleStyle = {},\n keyboardBehavior = Platform.OS === \"android\" ? \"extend\" : \"interactive\",\n keyboardBlurBehavior = \"restore\",\n androidKeyboardInputMode = \"adjustResize\",\n ...restOptions\n } = options;\n\n // Android 키보드 높이 감지\n useEffect(() => {\n if (Platform.OS === \"android\") {\n const keyboardDidShowListener = Keyboard.addListener(\n \"keyboardDidShow\",\n (e) => setKeyboardHeight(e.endCoordinates.height)\n );\n const keyboardDidHideListener = Keyboard.addListener(\n \"keyboardDidHide\",\n () => setKeyboardHeight(0)\n );\n\n return () => {\n keyboardDidShowListener.remove();\n keyboardDidHideListener.remove();\n };\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n const rafId = requestAnimationFrame(() => {\n bottomSheetRef.current?.expand();\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n return () => cancelAnimationFrame(rafId);\n } else {\n bottomSheetRef.current?.close();\n }\n }, [isOpen, overlayDispatch, overlayId]);\n\n const handleClose = useCallback(() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, [overlayDispatch, overlayId]);\n\n // 백드롭 렌더링\n const renderBackdrop = useCallback(\n (props: any) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={1}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior=\"close\"\n onPress={() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }}\n />\n ),\n [backdropOpacity, keyboardHeight]\n );\n // callbacks\n const handleSheetChange = useCallback((index: number) => {\n console.log(\"handleSheetChange\", index);\n }, []);\n\n if (!isOpen) return null;\n\n return (\n <BottomSheet\n ref={bottomSheetRef}\n onChange={handleSheetChange}\n android_keyboardInputMode={androidKeyboardInputMode}\n keyboardBehavior={keyboardBehavior}\n snapPoints={enableDynamicSizing ? undefined : snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n onClose={handleClose}\n keyboardBlurBehavior={keyboardBlurBehavior}\n index={0}\n backdropComponent={enableBackdrop ? renderBackdrop : undefined}\n backgroundStyle={[\n {\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n backgroundStyle,\n ]}\n handleStyle={[\n {\n backgroundColor: \"transparent\",\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n handleStyle,\n ]}\n enableDynamicSizing={enableDynamicSizing}\n animateOnMount={!reducedMotion}\n >\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n snapPoints={snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n keyboardHeight={keyboardHeight}\n {...restOptions}\n />\n </BottomSheet>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n contentContainer: {\n flex: 1,\n },\n});\n","import React, { type FC, memo, useEffect, useState } from \"react\";\nimport {\n Modal,\n View,\n TouchableWithoutFeedback,\n Animated,\n StyleSheet,\n Dimensions,\n Pressable,\n} from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype ModalControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n\nexport type ModalControllerComponent<T = {}> = FC<ModalControllerProps & T>;\n\ntype ContentModalControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: React.Dispatch<OverlayReducerAction>;\n controller: ModalControllerComponent | React.ReactElement;\n options?: {\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n };\n};\n\nconst { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get(\"window\");\n\nexport const ContentModalController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentModalControllerProps) => {\n const {\n modalType = \"center\",\n backdropOpacity = 0.5,\n animationType = \"fade\",\n swipeDirection,\n } = options;\n\n const [backdropAnimation] = useState(new Animated.Value(0));\n const [contentAnimation] = useState(new Animated.Value(0));\n\n useEffect(() => {\n if (isOpen) {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n\n // 애니메이션 시작\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n ]).start();\n } else {\n // 닫기 애니메이션\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start();\n }\n }, [\n isOpen,\n overlayDispatch,\n overlayId,\n backdropAnimation,\n contentAnimation,\n ]);\n\n const handleClose = () => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n };\n\n const getContainerStyle = () => {\n switch (modalType) {\n case \"bottom\":\n return styles.bottomContainer;\n case \"top\":\n return styles.topContainer;\n case \"left\":\n return styles.leftContainer;\n case \"right\":\n return styles.rightContainer;\n default: // center\n return styles.centerContainer;\n }\n };\n\n const getContentAnimationStyle = () => {\n const baseOpacity = {\n opacity: contentAnimation,\n };\n\n switch (modalType) {\n case \"bottom\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"top\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"left\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n case \"right\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n default: // center\n if (animationType === \"slide\") {\n return {\n ...baseOpacity,\n transform: [\n {\n scale: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [0.8, 1],\n }),\n },\n ],\n };\n }\n return baseOpacity;\n }\n };\n\n // Modal 대신 절대 위치 View 사용 (필요시)\n if (!isOpen) return null;\n\n return (\n <Modal\n visible={isOpen}\n transparent={true}\n animationType=\"none\"\n onRequestClose={handleClose}\n statusBarTranslucent={true}\n presentationStyle=\"overFullScreen\"\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={handleClose}>\n <Animated.View\n style={[\n styles.backdrop,\n {\n backgroundColor: `rgba(0, 0, 0, ${backdropOpacity})`,\n opacity: backdropAnimation,\n },\n ]}\n >\n <View style={StyleSheet.absoluteFill} pointerEvents=\"box-none\">\n <Animated.View\n style={[getContainerStyle(), getContentAnimationStyle()]}\n pointerEvents=\"box-none\"\n >\n <Pressable onPress={() => {}}>\n {React.isValidElement(Controller)\n ? React.cloneElement(\n Controller as React.ReactElement<any>,\n {\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n }\n )\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n modalType,\n backdropOpacity,\n animationType,\n swipeDirection,\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n })}\n </Pressable>\n </Animated.View>\n </View>\n </Animated.View>\n </Pressable>\n </Modal>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n backdrop: {\n ...StyleSheet.absoluteFillObject,\n },\n centerContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n },\n bottomContainer: {\n flex: 1,\n justifyContent: \"flex-end\",\n },\n topContainer: {\n flex: 1,\n justifyContent: \"flex-start\",\n },\n leftContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n },\n rightContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-end\",\n },\n});\n","import { useEffect } from \"react\";\nimport { createEmitter } from \"./emitter\";\n\nconst emitter = createEmitter();\n\n// React Native에서는 useEffect를 사용 (useLayoutEffect 대신)\nfunction useClientEffect(...args: Parameters<typeof useEffect>) {\n // RN에서는 항상 useEffect 실행\n useEffect(...args);\n}\n\n// 단순한 wrapper 함수\n// emitter.emit을 한번 감싼 이유는 나중에 로깅, 디버깅 등 추가 기능을 넣기 위함\nfunction dispatchEvent<Detail>(type: string, detail?: Detail) {\n emitter.emit(type, detail);\n}\n\n// 메인 팩토리 함수\n// 사용 예\n// createUseExternalEvents<OverlayEvents>('overlay-kit')\n// prefix의 역할:\n// - 'overlay-kit' → 실제 이벤트명은 overlay-kit:open, overlay-kit:close\n// - 네임스페이스로 이벤트 충돌 방지\n\nfunction createUseExternalEvents<\n EventHandlers extends Record<string, (params: any) => void>\n>(prefix: string) {\n function useExternalEvents(events: EventHandlers) {\n // 변환 과정:\n // 입력:\n // events = {\n // open: (data) => console.log('열기', data),\n // close: (id) => console.log('닫기', id)\n // }\n\n // 변환 결과:\n // handlers = {\n // 'overlay-kit:open': (event) => events.open(event),\n // 'overlay-kit:close': (event) => events.close(event)\n // }\n\n const handlers = Object.keys(events).reduce<Record<string, () => void>>(\n (prev, eventKey) => {\n const currentEventKeys = `${prefix}:${eventKey}`;\n\n return {\n ...prev,\n [currentEventKeys]: function (event: unknown) {\n events[eventKey](event);\n } as () => void,\n };\n },\n {}\n );\n\n useClientEffect(() => {\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]); // 🔥 기존 핸들러 제거\n // (중복 방지)\n emitter.on(eventKey, handlers[eventKey]); // 🔥 새로운 핸들러 등록\n });\n\n // 🧹 컴포넌트 언마운트시 정리\n return () =>\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]);\n });\n }, [handlers]);\n }\n\n // 타입 분석:\n // EventKey = 'open' | 'close' | 'closeAll'\n // Parameters<EventHandlers['open']> = [data: {component: Component, id:\n // string}]\n\n // const openEvent = createEvent('open');\n // openEvent의 타입: (data: {component: Component, id: string}) => void\n\n // openEvent({component: MyModal, id: '123'});\n // → dispatchEvent('overlay-kit:open', {component: MyModal, id: '123'})\n\n // payload[0]을 사용하는 이유:\n // 함수 호출: openEvent(arg1, arg2, arg3)\n // payload = [arg1, arg2, arg3]\n // payload[0] = arg1 (첫 번째 인자만 이벤트 데이터로 전달)\n\n function createEvent<EventKey extends keyof EventHandlers>(event: EventKey) {\n return (...payload: Parameters<EventHandlers[EventKey]>) =>\n dispatchEvent(`${prefix}:${String(event)}`, payload[0]);\n }\n\n return [useExternalEvents, createEvent] as const;\n}\n\n// 💡 이 패턴의 천재적인 점\n\n// 1. React 외부에서 React 내부 제어: overlay.open() 같은 명령형 API 가능\n// 2. 타입 안전성: TypeScript로 이벤트 타입 완벽 추론\n// 3. 메모리 안전: React Hook 생명주기와 완벽 동기화\n// 4. 플랫폼 호환: 웹/RN 모두 지원\n// 5. 네임스페이스: 이벤트 충돌 방지\n\nexport { createUseExternalEvents };\n","\n// 이벤트 이름\nexport type EventType = string | symbol;\n\n// 이벤트 핸들러\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;\n\n// 이벤트 핸들러 목록\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;\n\n// 이벤트 핸들러 맵\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | '*',\n EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\n// 이벤트 발행기\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n all: EventHandlerMap<Events>;\n\n on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n on(type: '*', handler: WildcardHandler<Events>): void;\n\n off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;\n off(type: '*', handler: WildcardHandler<Events>): void;\n\n emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;\n}\n\nexport function createEmitter<Events extends Record<EventType, unknown>>(\n all?: EventHandlerMap<Events>\n): Emitter<Events> {\n type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>;\n all = all || new Map();\n\n return {\n all,\n on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n handlers.push(handler);\n } else {\n all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n }\n },\n off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n all!.set(type, []);\n }\n }\n },\n emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n let handlers = all!.get(type);\n if (handlers) {\n (handlers as EventHandlerList<Events[keyof Events]>).slice().forEach((handler) => {\n handler(evt!);\n });\n }\n\n handlers = all!.get('*');\n if (handlers) {\n (handlers as WildCardEventHandlerList<Events>).slice().forEach((handler) => {\n handler(type, evt!);\n });\n }\n },\n };\n}","export function randomId() {\n return `overlay-kit-${Math.random().toString(36).slice(2, 11)}`;\n}","// 사용자가 실제로 사용하는 API 를 만드는 팩토리\n// overlay.open(), overlay.close 등\n\nimport React from \"react\";\nimport {\n OverlayAsyncControllerComponent,\n OverlayControllerComponent,\n} from \"./context/provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./context/provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./context/provider/modal-controller\";\nimport { createUseExternalEvents } from \"./utils/create-use-external-events\";\nimport { randomId } from \"./utils/random-id\";\n\nexport type OverlayEvent = {\n open: (args: {\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement;\n overlayId: string;\n componentKey: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n options?: any;\n }) => void;\n close: (overlayId: string) => void;\n unmount: (overlayId: string) => void;\n closeAll: () => void;\n unmountAll: () => void;\n};\n\ntype OpenOverlayOptions = {\n overlayId?: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n // BottomSheet options\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Modal options\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n enableDynamicSizing?: boolean;\n animationType?:\n | \"none\"\n | \"slide\"\n | \"fade\"\n | \"bounceIn\"\n | \"bounceInDown\"\n | \"bounceInUp\"\n | \"bounceInLeft\"\n | \"bounceInRight\"\n | \"bounceOut\"\n | \"bounceOutDown\"\n | \"bounceOutUp\"\n | \"bounceOutLeft\"\n | \"bounceOutRight\"\n | \"fadeIn\"\n | \"fadeInDown\"\n | \"fadeInDownBig\"\n | \"fadeInUp\"\n | \"fadeInUpBig\"\n | \"fadeInLeft\"\n | \"fadeInLeftBig\"\n | \"fadeInRight\"\n | \"fadeInRightBig\"\n | \"fadeOut\"\n | \"fadeOutDown\"\n | \"fadeOutDownBig\"\n | \"fadeOutUp\"\n | \"fadeOutUpBig\"\n | \"fadeOutLeft\"\n | \"fadeOutLeftBig\"\n | \"fadeOutRight\"\n | \"fadeOutRightBig\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n// id 받아\nexport function createOverlay(overlayId: string) {\n const [useOverlayEvent, createEvent] = createUseExternalEvents<OverlayEvent>(\n `${overlayId}/overlay-kit`\n );\n\n const open = (\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement,\n options?: OpenOverlayOptions\n ) => {\n const overlayId = options?.overlayId ?? randomId();\n const componentKey = randomId();\n const overlayType = options?.overlayType ?? \"overlay\";\n\n const dispatchOpenEvent = createEvent(\"open\");\n\n // 옵션에서 overlayType과 overlayId를 제외한 나머지를 options로 전달\n const { overlayId: _, overlayType: __, ...restOptions } = options || {};\n\n dispatchOpenEvent({\n controller,\n overlayId,\n componentKey,\n overlayType,\n options: restOptions,\n });\n return overlayId;\n };\n\n // openAsync는 모든 overlay 타입에서 사용 가능\n const openAsync = async <T>(\n controller:\n | OverlayAsyncControllerComponent<T>\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | ((props: any) => any),\n options?: OpenOverlayOptions\n ) => {\n return new Promise<T>((resolve) => {\n const wrappedController = (\n overlayProps: any,\n ...deprecatedLegacyContext: any[]\n ) => {\n const close = (param?: T) => {\n resolve(param as T);\n overlayProps.close();\n };\n const unmount = (param?: T) => {\n resolve(param as T);\n overlayProps.unmount();\n };\n const props = { ...overlayProps, close, unmount };\n return controller(props);\n };\n\n open(wrappedController, options);\n });\n };\n const close = createEvent(\"close\");\n const unmount = createEvent(\"unmount\");\n const closeAll = createEvent(\"closeAll\");\n const unmountAll = createEvent(\"unmountAll\");\n return {\n open,\n openAsync,\n close,\n unmount,\n closeAll,\n unmountAll,\n useOverlayEvent,\n };\n}\n","import { type Provider, createContext, useContext } from 'react';\n\ntype NullSymbolType = typeof NullSymbol;\nconst NullSymbol = Symbol('Null');\n\nexport type CreateContextReturn<T> = [Provider<T>, () => T];\n\nexport function createSafeContext<T>(displayName?: string): CreateContextReturn<T> {\n const Context = createContext<T | NullSymbolType>(NullSymbol);\n Context.displayName = displayName ?? 'SafeContext';\n\n function useSafeContext() {\n const context = useContext(Context);\n\n if (context === NullSymbol) {\n const error = new Error(`[${Context.displayName}]: Provider not found.`);\n error.name = '[Error] Context';\n\n throw error;\n }\n\n return context;\n }\n\n return [Context.Provider as any, useSafeContext];\n}\n","import { createSafeContext } from '../utils/create-safe-context';\nimport { type OverlayData } from './reducer';\n\n\nexport function createOverlaySafeContext() {\n const [OverlayContextProvider, useOverlayContext] = createSafeContext<OverlayData>('overlay-kit/OverlayContext');\n\n function useCurrentOverlay() {\n return useOverlayContext().current;\n }\n\n function useOverlayData() {\n return useOverlayContext().overlayData;\n }\n\n return { OverlayContextProvider, useCurrentOverlay, useOverlayData };\n}\n","import { OverlayControllerComponent } from \"./provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./provider/modal-controller\";\n\ntype OverlayId = string;\ntype OverlayItem = {\n /**\n * @description 오버레이 고유한 ID\n */\n id : OverlayId;\n /**\n * @description 오버레이 컴포넌트의 고유한 키\n * 컴포넌트가 언마운트시 사용됩니다.\n */\n componentKey: string;\n isOpen: boolean;\n isMounted: boolean;\n controller: OverlayControllerComponent | BottomSheetControllerComponent | ModalControllerComponent;\n overlayType?: 'overlay' | 'bottomSheet' | 'modal';\n options?: any;\n}\nexport type OverlayData = {\n current: OverlayId | null; // 현재 열려있는 오버레이 ID\n overlayOrderList: OverlayId[];\n overlayData: Record<OverlayId, OverlayItem>;\n}\nexport type OverlayReducerAction =\n | { type: 'ADD'; overlay: OverlayItem }\n | { type: 'OPEN'; overlayId: string }\n | { type: 'CLOSE'; overlayId: string }\n | { type: 'REMOVE'; overlayId: string }\n | { type: 'CLOSE_ALL' }\n | { type: 'REMOVE_ALL' };\n\n/**\n * 오버레이를 닫거나 제거할 때, 어떤 오버레이를 현재(current)로 지정할지 결정합니다.\n *\n * @description 마지막 오버레이를 닫을 경우, 그 이전 오버레이를 현재로 지정합니다.\n * @description 중간에 있는 오버레이를 닫을 경우, 마지막 오버레이를 현재로 지정합니다.\n *\n * @example open - [1, 2, 3, 4]\n * close 2 => current: 4\n * close 4 => current: 3\n * close 3 => current: 1\n * close 1 => current: null\n *\n * @param overlayOrderList 오버레이 ID가 순서대로 담긴 리스트\n * @param overlayData 오버레이 데이터 맵\n * @param targetOverlayId 닫거나 제거하려는 오버레이의 ID\n * @returns 현재로 지정될 오버레이의 ID, 없으면 null\n */\nexport const determineCurrentOverlayId = (overlayOrderList: OverlayId[], overlayData: Record<OverlayId, OverlayItem>, targetOverlayId: OverlayId): OverlayId | null => {\n // 1단계: 열린 오버레이들만 필터링\n\n const openedOverlayOrderList = overlayOrderList.filter(\n (orderedOverlayId) => overlayData[orderedOverlayId].isOpen === true\n );\n // 2단계: 닫힐 오버레이의 위치 찾기\n const targetIndexInOpenedList = openedOverlayOrderList.findIndex((item) => item === targetOverlayId);\n\n // 3단계: 다음 활성 오버레이 결정\n return targetIndexInOpenedList === openedOverlayOrderList.length - 1\n ? openedOverlayOrderList[targetIndexInOpenedList - 1] ?? null // 마지막이면 이전 것\n : openedOverlayOrderList[openedOverlayOrderList.length - 1] ?? null;// 중간이면 최상위\n\n}\n\n/** 동작 예시:\n * \n *\n * // 상황: 오버레이 [1, 2, 3, 4]가 순서대로 열려있음\n * overlayOrderList = [\"modal-1\", \"modal-2\", \"modal-3\", \"modal-4\"];\n * // 모두 isOpen: true\n *\n * // 케이스 1: 최상위(4번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-4\");\n * // → \"modal-3\" (바로 아래가 활성화)\n *\n * // 케이스 2: 중간(2번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-2\");\n * // → \"modal-4\" (최상위가 여전히 활성)\n *\n * // 케이스 3: 마지막 남은 것 닫기\n * determineCurrentOverlayId([\"modal-1\"], data, \"modal-1\");\n * // → null (더 이상 활성 오버레이 없음)\n */\n\n// 상태 변경 로직\nexport function overlayReducer(state: OverlayData, action: OverlayReducerAction): OverlayData {\n switch (action.type) {\n case 'ADD': {\n if (state.overlayData[action.overlay.id] != null && state.overlayData[action.overlay.id].isOpen === false) {\n const overlay = state.overlayData[action.overlay.id];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n current: action.overlay.id,\n overlayData: {\n ...state.overlayData,\n [action.overlay.id]: { ...overlay, isOpen: true },\n },\n };\n }\n\n const isExisted = state.overlayOrderList.includes(action.overlay.id);\n\n if (isExisted && state.overlayData[action.overlay.id].isOpen === true) {\n throw new Error(\n `You can't open the multiple overlays with the same overlayId(${action.overlay.id}). Please set a different id.`\n );\n }\n\n return {\n current: action.overlay.id,\n /**\n * @description Brings the overlay to the front when reopened after closing without unmounting.\n */\n overlayOrderList: [...state.overlayOrderList.filter((item) => item !== action.overlay.id), action.overlay.id],\n overlayData: isExisted\n ? state.overlayData\n : {\n ...state.overlayData,\n [action.overlay.id]: action.overlay,\n },\n };\n }\n case 'OPEN': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: { ...overlay, isOpen: true, isMounted: true },\n },\n };\n }\n case 'CLOSE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already closed\n if (overlay == null || !overlay.isOpen) {\n return state;\n }\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n ...state,\n current: currentOverlayId,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: {\n ...state.overlayData[action.overlayId],\n isOpen: false,\n },\n },\n };\n }\n case 'REMOVE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist\n if (overlay == null) {\n return state;\n }\n\n const remainingOverlays = state.overlayOrderList.filter((item) => item !== action.overlayId);\n if (state.overlayOrderList.length === remainingOverlays.length) {\n return state;\n }\n\n const copiedOverlayData = { ...state.overlayData };\n delete copiedOverlayData[action.overlayId];\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n current: currentOverlayId,\n overlayOrderList: remainingOverlays,\n overlayData: copiedOverlayData,\n };\n }\n case 'CLOSE_ALL': {\n // ignore if there is no overlay\n if (Object.keys(state.overlayData).length === 0) {\n return state;\n }\n\n return {\n ...state,\n current: null,\n overlayData: Object.keys(state.overlayData).reduce(\n (prev, curr) => ({\n ...prev,\n [curr]: {\n ...state.overlayData[curr],\n isOpen: false,\n } satisfies OverlayItem,\n }),\n {} satisfies Record<string, OverlayItem>\n ),\n };\n }\n case 'REMOVE_ALL': {\n return { current: null, overlayOrderList: [], overlayData: {} };\n }\n }\n}","import { createOverlayProvider } from '../context/provider';\n\nexport const { overlay, OverlayProvider, useCurrentOverlay, useOverlayData } = createOverlayProvider();\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function experimental_createOverlayContext() {\n return createOverlayProvider();\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAKO;;;ACLP,mBAA+D;AAyCzD;AAdC,IAAM,+BAA2B;AAAA,EACtC,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd,MAAqC;AACnC,gCAAU,MAAM;AACd,mBAAa,MAAM;AACjB,wBAAgB,EAAE,MAAM,QAAQ,UAAU,CAAC;AAAA,MAC7C,CAAC;AAAA,IACH,GAAG,CAAC,iBAAiB,SAAS,CAAC;AAE/B,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,OAAO,MAAM,gBAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,QACzD,SAAS,MAAM,gBAAgB,EAAE,MAAM,UAAU,UAAU,CAAC;AAAA;AAAA,IAC9D;AAAA,EAEJ;AACF;;;ACjDA,IAAAC,gBAQO;AACP,0BAQO;AACP,0BAQO;AACP,qCAAiC;AAwIzB,IAAAC,sBAAA;AAtED,IAAM,mCAA+B;AAAA,EAC1C,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,UAAU,CAAC;AAAA,EACb,MAAyC;AACvC,UAAM,qBAAiB,sBAAoB,IAAI;AAC/C,UAAM,oBAAgB,iDAAiB;AACvC,UAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,CAAC;AAQtD,UAYI,cAXF;AAAA;AAAA,MACA,uBAAuB;AAAA,MACvB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,sBAAsB;AAAA,MACtB,kBAAkB,CAAC;AAAA,MACnB,cAAc,CAAC;AAAA,MACf,mBAAmB,6BAAS,OAAO,YAAY,WAAW;AAAA,MAC1D,uBAAuB;AAAA,MACvB,2BAA2B;AAAA,IAzHjC,IA2HQ,IADC,wBACD,IADC;AAAA,MAVH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAKF,iCAAU,MAAM;AACd,UAAI,6BAAS,OAAO,WAAW;AAC7B,cAAM,0BAA0B,6BAAS;AAAA,UACvC;AAAA,UACA,CAAC,MAAM,kBAAkB,EAAE,eAAe,MAAM;AAAA,QAClD;AACA,cAAM,0BAA0B,6BAAS;AAAA,UACvC;AAAA,UACA,MAAM,kBAAkB,CAAC;AAAA,QAC3B;AAEA,eAAO,MAAM;AACX,kCAAwB,OAAO;AAC/B,kCAAwB,OAAO;AAAA,QACjC;AAAA,MACF;AAAA,IACF,GAAG,CAAC,CAAC;AAEL,iCAAU,MAAM;AAhJpB,UAAAC;AAiJM,UAAI,QAAQ;AACV,cAAM,QAAQ,sBAAsB,MAAM;AAlJlD,cAAAA;AAmJU,WAAAA,MAAA,eAAe,YAAf,gBAAAA,IAAwB;AACxB,0BAAgB,EAAE,MAAM,QAAQ,UAAU,CAAC;AAAA,QAC7C,CAAC;AACD,eAAO,MAAM,qBAAqB,KAAK;AAAA,MACzC,OAAO;AACL,SAAAA,MAAA,eAAe,YAAf,gBAAAA,IAAwB;AAAA,MAC1B;AAAA,IACF,GAAG,CAAC,QAAQ,iBAAiB,SAAS,CAAC;AAEvC,UAAM,kBAAc,2BAAY,MAAM;AACpC,sBAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,IAC9C,GAAG,CAAC,iBAAiB,SAAS,CAAC;AAG/B,UAAM,qBAAiB;AAAA,MACrB,CAAC,UACC;AAAA,QAAC;AAAA,yCACK,QADL;AAAA,UAEC,gBAAgB;AAAA,UAChB,mBAAmB;AAAA,UACnB,SAAS;AAAA,UACT,eAAc;AAAA,UACd,SAAS,MAAM;AACb,4BAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,UAC9C;AAAA;AAAA,MACF;AAAA,MAEF,CAAC,iBAAiB,cAAc;AAAA,IAClC;AAEA,UAAM,wBAAoB,2BAAY,CAAC,UAAkB;AACvD,cAAQ,IAAI,qBAAqB,KAAK;AAAA,IACxC,GAAG,CAAC,CAAC;AAEL,QAAI,CAAC,OAAQ,QAAO;AAEpB,WACE;AAAA,MAAC,oBAAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,UAAU;AAAA,QACV,2BAA2B;AAAA,QAC3B;AAAA,QACA,YAAY,sBAAsB,SAAY;AAAA,QAC9C;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA,OAAO;AAAA,QACP,mBAAmB,iBAAiB,iBAAiB;AAAA,QACrD,iBAAiB;AAAA,UACf;AAAA,YACE,qBAAqB;AAAA,YACrB,sBAAsB;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAAA,QACA,aAAa;AAAA,UACX;AAAA,YACE,iBAAiB;AAAA,YACjB,qBAAqB;AAAA,YACrB,sBAAsB;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA,gBAAgB,CAAC;AAAA,QAEjB;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,OAAO,MAAM,gBAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,YACzD,SAAS,MAAM,gBAAgB,EAAE,MAAM,UAAU,UAAU,CAAC;AAAA,YAC5D;AAAA,aACI;AAAA,QACN;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,IAAM,SAAS,+BAAW,OAAO;AAAA,EAC/B,kBAAkB;AAAA,IAChB,MAAM;AAAA,EACR;AACF,CAAC;;;ACxOD,IAAAC,gBAA0D;AAC1D,IAAAC,uBAQO;AA2NS,IAAAC,sBAAA;AApLhB,IAAM,EAAE,OAAO,cAAc,QAAQ,cAAc,IAAI,gCAAW,IAAI,QAAQ;AAEvE,IAAM,6BAAyB;AAAA,EACpC,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,UAAU,CAAC;AAAA,EACb,MAAmC;AACjC,UAAM;AAAA,MACJ,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB;AAAA,IACF,IAAI;AAEJ,UAAM,CAAC,iBAAiB,QAAI,wBAAS,IAAI,8BAAS,MAAM,CAAC,CAAC;AAC1D,UAAM,CAAC,gBAAgB,QAAI,wBAAS,IAAI,8BAAS,MAAM,CAAC,CAAC;AAEzD,iCAAU,MAAM;AACd,UAAI,QAAQ;AACV,qBAAa,MAAM;AACjB,0BAAgB,EAAE,MAAM,QAAQ,UAAU,CAAC;AAAA,QAC7C,CAAC;AAGD,sCAAS,SAAS;AAAA,UAChB,8BAAS,OAAO,mBAAmB;AAAA,YACjC,SAAS;AAAA,YACT,UAAU;AAAA,YACV,iBAAiB;AAAA,UACnB,CAAC;AAAA,UACD,8BAAS,OAAO,kBAAkB;AAAA,YAChC,SAAS;AAAA,YACT,UAAU;AAAA,YACV,iBAAiB;AAAA,UACnB,CAAC;AAAA,QACH,CAAC,EAAE,MAAM;AAAA,MACX,OAAO;AAEL,sCAAS,SAAS;AAAA,UAChB,8BAAS,OAAO,mBAAmB;AAAA,YACjC,SAAS;AAAA,YACT,UAAU;AAAA,YACV,iBAAiB;AAAA,UACnB,CAAC;AAAA,UACD,8BAAS,OAAO,kBAAkB;AAAA,YAChC,SAAS;AAAA,YACT,UAAU;AAAA,YACV,iBAAiB;AAAA,UACnB,CAAC;AAAA,QACH,CAAC,EAAE,MAAM;AAAA,MACX;AAAA,IACF,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,cAAc,MAAM;AACxB,sBAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,IAC9C;AAEA,UAAM,oBAAoB,MAAM;AAC9B,cAAQ,WAAW;AAAA,QACjB,KAAK;AACH,iBAAOC,QAAO;AAAA,QAChB,KAAK;AACH,iBAAOA,QAAO;AAAA,QAChB,KAAK;AACH,iBAAOA,QAAO;AAAA,QAChB,KAAK;AACH,iBAAOA,QAAO;AAAA,QAChB;AACE,iBAAOA,QAAO;AAAA,MAClB;AAAA,IACF;AAEA,UAAM,2BAA2B,MAAM;AACrC,YAAM,cAAc;AAAA,QAClB,SAAS;AAAA,MACX;AAEA,cAAQ,WAAW;AAAA,QACjB,KAAK;AACH,iBAAO,iCACF,cADE;AAAA,YAEL,WAAW;AAAA,cACT;AAAA,gBACE,YAAY,iBAAiB,YAAY;AAAA,kBACvC,YAAY,CAAC,GAAG,CAAC;AAAA,kBACjB,aAAa,CAAC,eAAe,CAAC;AAAA,gBAChC,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF,KAAK;AACH,iBAAO,iCACF,cADE;AAAA,YAEL,WAAW;AAAA,cACT;AAAA,gBACE,YAAY,iBAAiB,YAAY;AAAA,kBACvC,YAAY,CAAC,GAAG,CAAC;AAAA,kBACjB,aAAa,CAAC,CAAC,eAAe,CAAC;AAAA,gBACjC,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF,KAAK;AACH,iBAAO,iCACF,cADE;AAAA,YAEL,WAAW;AAAA,cACT;AAAA,gBACE,YAAY,iBAAiB,YAAY;AAAA,kBACvC,YAAY,CAAC,GAAG,CAAC;AAAA,kBACjB,aAAa,CAAC,CAAC,cAAc,CAAC;AAAA,gBAChC,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF,KAAK;AACH,iBAAO,iCACF,cADE;AAAA,YAEL,WAAW;AAAA,cACT;AAAA,gBACE,YAAY,iBAAiB,YAAY;AAAA,kBACvC,YAAY,CAAC,GAAG,CAAC;AAAA,kBACjB,aAAa,CAAC,cAAc,CAAC;AAAA,gBAC/B,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACE,cAAI,kBAAkB,SAAS;AAC7B,mBAAO,iCACF,cADE;AAAA,cAEL,WAAW;AAAA,gBACT;AAAA,kBACE,OAAO,iBAAiB,YAAY;AAAA,oBAClC,YAAY,CAAC,GAAG,CAAC;AAAA,oBACjB,aAAa,CAAC,KAAK,CAAC;AAAA,kBACtB,CAAC;AAAA,gBACH;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,MACX;AAAA,IACF;AAGA,QAAI,CAAC,OAAQ,QAAO;AAEpB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,aAAa;AAAA,QACb,eAAc;AAAA,QACd,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,mBAAkB;AAAA,QAElB,uDAAC,kCAAU,OAAO,gCAAW,cAAc,SAAS,aAClD;AAAA,UAAC,8BAAS;AAAA,UAAT;AAAA,YACC,OAAO;AAAA,cACLA,QAAO;AAAA,cACP;AAAA,gBACE,iBAAiB,iBAAiB,eAAe;AAAA,gBACjD,SAAS;AAAA,cACX;AAAA,YACF;AAAA,YAEA,uDAAC,6BAAK,OAAO,gCAAW,cAAc,eAAc,YAClD;AAAA,cAAC,8BAAS;AAAA,cAAT;AAAA,gBACC,OAAO,CAAC,kBAAkB,GAAG,yBAAyB,CAAC;AAAA,gBACvD,eAAc;AAAA,gBAEd,uDAAC,kCAAU,SAAS,MAAM;AAAA,gBAAC,GACxB,wBAAAC,QAAM,eAAe,UAAU,IAC5B,cAAAA,QAAM;AAAA,kBACJ;AAAA,kBACA;AAAA,oBACE,OAAO,MACL,gBAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,oBAC9C,SAAS,MACP,gBAAgB,EAAE,MAAM,UAAU,UAAU,CAAC;AAAA,kBACjD;AAAA,gBACF,IACA,cAAAA,QAAM,cAAc,YAAmB;AAAA,kBACrC;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,OAAO,MACL,gBAAgB,EAAE,MAAM,SAAS,UAAU,CAAC;AAAA,kBAC9C,SAAS,MACP,gBAAgB,EAAE,MAAM,UAAU,UAAU,CAAC;AAAA,gBACjD,CAAC,GACP;AAAA;AAAA,YACF,GACF;AAAA;AAAA,QACF,GACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,IAAMD,UAAS,gCAAW,OAAO;AAAA,EAC/B,UAAU,mBACL,gCAAW;AAAA,EAEhB,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,mBAAmB;AAAA,EACrB;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,gBAAgB;AAAA,EAClB;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,gBAAgB;AAAA,EAClB;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,YAAY;AAAA,EACd;AAAA,EACA,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,YAAY;AAAA,EACd;AACF,CAAC;;;ACjSD,IAAAE,gBAA0B;;;ACgCnB,SAAS,cACd,KACiB;AAEjB,QAAM,OAAO,oBAAI,IAAI;AAErB,SAAO;AAAA,IACL;AAAA,IACA,GAA6B,MAAW,SAA8B;AACpE,YAAM,WAAmD,IAAK,IAAI,IAAI;AACtE,UAAI,UAAU;AACZ,iBAAS,KAAK,OAAO;AAAA,MACvB,OAAO;AACL,YAAK,IAAI,MAAM,CAAC,OAAO,CAA2C;AAAA,MACpE;AAAA,IACF;AAAA,IACA,IAA8B,MAAW,SAA+B;AACtE,YAAM,WAAmD,IAAK,IAAI,IAAI;AACtE,UAAI,UAAU;AACZ,YAAI,SAAS;AACX,mBAAS,OAAO,SAAS,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,QACpD,OAAO;AACL,cAAK,IAAI,MAAM,CAAC,CAAC;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAA+B,MAAW,KAAmB;AAC3D,UAAI,WAAW,IAAK,IAAI,IAAI;AAC5B,UAAI,UAAU;AACZ,QAAC,SAAoD,MAAM,EAAE,QAAQ,CAAC,YAAY;AAChF,kBAAQ,GAAI;AAAA,QACd,CAAC;AAAA,MACH;AAEA,iBAAW,IAAK,IAAI,GAAG;AACvB,UAAI,UAAU;AACZ,QAAC,SAA8C,MAAM,EAAE,QAAQ,CAAC,YAAY;AAC1E,kBAAQ,MAAM,GAAI;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ADvEA,IAAM,UAAU,cAAc;AAG9B,SAAS,mBAAmB,MAAoC;AAE9D,+BAAU,GAAG,IAAI;AACnB;AAIA,SAAS,cAAsB,MAAc,QAAiB;AAC5D,UAAQ,KAAK,MAAM,MAAM;AAC3B;AASA,SAAS,wBAEP,QAAgB;AAChB,WAAS,kBAAkB,QAAuB;AAchD,UAAM,WAAW,OAAO,KAAK,MAAM,EAAE;AAAA,MACnC,CAAC,MAAM,aAAa;AAClB,cAAM,mBAAmB,GAAG,MAAM,IAAI,QAAQ;AAE9C,eAAO,iCACF,OADE;AAAA,UAEL,CAAC,gBAAgB,GAAG,SAAU,OAAgB;AAC5C,mBAAO,QAAQ,EAAE,KAAK;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,MACA,CAAC;AAAA,IACH;AAEA,oBAAgB,MAAM;AACpB,aAAO,KAAK,QAAQ,EAAE,QAAQ,CAAC,aAAa;AAC1C,gBAAQ,IAAI,UAAU,SAAS,QAAQ,CAAC;AAExC,gBAAQ,GAAG,UAAU,SAAS,QAAQ,CAAC;AAAA,MACzC,CAAC;AAGD,aAAO,MACL,OAAO,KAAK,QAAQ,EAAE,QAAQ,CAAC,aAAa;AAC1C,gBAAQ,IAAI,UAAU,SAAS,QAAQ,CAAC;AAAA,MAC1C,CAAC;AAAA,IACL,GAAG,CAAC,QAAQ,CAAC;AAAA,EACf;AAkBA,WAAS,YAAkD,OAAiB;AAC1E,WAAO,IAAI,YACT,cAAc,GAAG,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,QAAQ,CAAC,CAAC;AAAA,EAC1D;AAEA,SAAO,CAAC,mBAAmB,WAAW;AACxC;;;AE5FO,SAAS,WAAW;AACzB,SAAO,eAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAC/D;;;ACkFO,SAAS,cAAc,WAAmB;AAC/C,QAAM,CAAC,iBAAiB,WAAW,IAAI;AAAA,IACrC,GAAG,SAAS;AAAA,EACd;AAEA,QAAM,OAAO,CACX,YAKA,YACG;AAhGP;AAiGI,UAAMC,cAAY,wCAAS,cAAT,YAAsB,SAAS;AACjD,UAAM,eAAe,SAAS;AAC9B,UAAM,eAAc,wCAAS,gBAAT,YAAwB;AAE5C,UAAM,oBAAoB,YAAY,MAAM;AAG5C,UAA0D,gBAAW,CAAC,GAA9D,aAAW,GAAG,aAAa,GAxGvC,IAwG8D,IAAhB,wBAAgB,IAAhB,CAAlC,aAAc;AAEtB,sBAAkB;AAAA,MAChB;AAAA,MACA,WAAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AACD,WAAOA;AAAA,EACT;AAGA,QAAM,YAAY,OAChB,YAKA,YACG;AACH,WAAO,IAAI,QAAW,CAAC,YAAY;AACjC,YAAM,oBAAoB,CACxB,iBACG,4BACA;AACH,cAAMC,SAAQ,CAAC,UAAc;AAC3B,kBAAQ,KAAU;AAClB,uBAAa,MAAM;AAAA,QACrB;AACA,cAAMC,WAAU,CAAC,UAAc;AAC7B,kBAAQ,KAAU;AAClB,uBAAa,QAAQ;AAAA,QACvB;AACA,cAAM,QAAQ,iCAAK,eAAL,EAAmB,OAAAD,QAAO,SAAAC,SAAQ;AAChD,eAAO,WAAW,KAAK;AAAA,MACzB;AAEA,WAAK,mBAAmB,OAAO;AAAA,IACjC,CAAC;AAAA,EACH;AACA,QAAM,QAAQ,YAAY,OAAO;AACjC,QAAM,UAAU,YAAY,SAAS;AACrC,QAAM,WAAW,YAAY,UAAU;AACvC,QAAM,aAAa,YAAY,YAAY;AAC3C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC9JA,IAAAC,gBAAyD;AAGzD,IAAM,aAAa,OAAO,MAAM;AAIzB,SAAS,kBAAqB,aAA8C;AACjF,QAAM,cAAU,6BAAkC,UAAU;AAC5D,UAAQ,cAAc,oCAAe;AAErC,WAAS,iBAAiB;AACxB,UAAM,cAAU,0BAAW,OAAO;AAElC,QAAI,YAAY,YAAY;AAC1B,YAAM,QAAQ,IAAI,MAAM,IAAI,QAAQ,WAAW,wBAAwB;AACvE,YAAM,OAAO;AAEb,YAAM;AAAA,IACR;AAEA,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,QAAQ,UAAiB,cAAc;AACjD;;;ACrBO,SAAS,2BAA2B;AACzC,QAAM,CAAC,wBAAwB,iBAAiB,IAAI,kBAA+B,4BAA4B;AAE/G,WAASC,qBAAoB;AAC3B,WAAO,kBAAkB,EAAE;AAAA,EAC7B;AAEA,WAASC,kBAAiB;AACxB,WAAO,kBAAkB,EAAE;AAAA,EAC7B;AAEA,SAAO,EAAE,wBAAwB,mBAAAD,oBAAmB,gBAAAC,gBAAe;AACrE;;;ACmCO,IAAM,4BAA4B,CAAC,kBAA+B,aAA6C,oBAAiD;AAnDvK;AAsDI,QAAM,yBAAyB,iBAAiB;AAAA,IAChD,CAAC,qBAAqB,YAAY,gBAAgB,EAAE,WAAW;AAAA,EACjE;AAEE,QAAM,0BAA0B,uBAAuB,UAAU,CAAC,SAAS,SAAS,eAAe;AAGjG,SAAO,4BAA4B,uBAAuB,SAAS,KACnE,4BAAuB,0BAA0B,CAAC,MAAlD,YAAuD,QACvD,4BAAuB,uBAAuB,SAAS,CAAC,MAAxD,YAA6D;AAEnE;AAuBO,SAAS,eAAe,OAAoB,QAA2C;AAC5F,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK,OAAO;AACV,UAAI,MAAM,YAAY,OAAO,QAAQ,EAAE,KAAK,QAAQ,MAAM,YAAY,OAAO,QAAQ,EAAE,EAAE,WAAW,OAAO;AACzG,cAAMC,WAAU,MAAM,YAAY,OAAO,QAAQ,EAAE;AAGnD,YAAIA,YAAW,QAAQA,SAAQ,QAAQ;AACrC,iBAAO;AAAA,QACT;AAEA,eAAO,iCACF,QADE;AAAA,UAEL,SAAS,OAAO,QAAQ;AAAA,UACxB,aAAa,iCACR,MAAM,cADE;AAAA,YAEX,CAAC,OAAO,QAAQ,EAAE,GAAG,iCAAKA,WAAL,EAAc,QAAQ,KAAK;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YAAY,MAAM,iBAAiB,SAAS,OAAO,QAAQ,EAAE;AAEnE,UAAI,aAAa,MAAM,YAAY,OAAO,QAAQ,EAAE,EAAE,WAAW,MAAM;AACrE,cAAM,IAAI;AAAA,UACR,gEAAgE,OAAO,QAAQ,EAAE;AAAA,QACnF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,QAIxB,kBAAkB,CAAC,GAAG,MAAM,iBAAiB,OAAO,CAAC,SAAS,SAAS,OAAO,QAAQ,EAAE,GAAG,OAAO,QAAQ,EAAE;AAAA,QAC5G,aAAa,YACT,MAAM,cACN,iCACK,MAAM,cADX;AAAA,UAEE,CAAC,OAAO,QAAQ,EAAE,GAAG,OAAO;AAAA,QAC9B;AAAA,MACN;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,YAAMA,WAAU,MAAM,YAAY,OAAO,SAAS;AAGlD,UAAIA,YAAW,QAAQA,SAAQ,QAAQ;AACrC,eAAO;AAAA,MACT;AAEA,aAAO,iCACF,QADE;AAAA,QAEL,aAAa,iCACR,MAAM,cADE;AAAA,UAEX,CAAC,OAAO,SAAS,GAAG,iCAAKA,WAAL,EAAc,QAAQ,MAAM,WAAW,KAAK;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AACZ,YAAMA,WAAU,MAAM,YAAY,OAAO,SAAS;AAGlD,UAAIA,YAAW,QAAQ,CAACA,SAAQ,QAAQ;AACtC,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB,0BAA0B,MAAM,kBAAkB,MAAM,aAAa,OAAO,SAAS;AAE9G,aAAO,iCACF,QADE;AAAA,QAEL,SAAS;AAAA,QACT,aAAa,iCACR,MAAM,cADE;AAAA,UAEX,CAAC,OAAO,SAAS,GAAG,iCACf,MAAM,YAAY,OAAO,SAAS,IADnB;AAAA,YAElB,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,YAAMA,WAAU,MAAM,YAAY,OAAO,SAAS;AAGlD,UAAIA,YAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAEA,YAAM,oBAAoB,MAAM,iBAAiB,OAAO,CAAC,SAAS,SAAS,OAAO,SAAS;AAC3F,UAAI,MAAM,iBAAiB,WAAW,kBAAkB,QAAQ;AAC9D,eAAO;AAAA,MACT;AAEA,YAAM,oBAAoB,mBAAK,MAAM;AACrC,aAAO,kBAAkB,OAAO,SAAS;AAEzC,YAAM,mBAAmB,0BAA0B,MAAM,kBAAkB,MAAM,aAAa,OAAO,SAAS;AAE9G,aAAO;AAAA,QACL,SAAS;AAAA,QACT,kBAAkB;AAAA,QAClB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAEhB,UAAI,OAAO,KAAK,MAAM,WAAW,EAAE,WAAW,GAAG;AAC/C,eAAO;AAAA,MACT;AAEA,aAAO,iCACF,QADE;AAAA,QAEL,SAAS;AAAA,QACT,aAAa,OAAO,KAAK,MAAM,WAAW,EAAE;AAAA,UAC1C,CAAC,MAAM,SAAU,iCACZ,OADY;AAAA,YAEf,CAAC,IAAI,GAAG,iCACH,MAAM,YAAY,IAAI,IADnB;AAAA,cAEN,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,UACA,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,cAAc;AACjB,aAAO,EAAE,SAAS,MAAM,kBAAkB,CAAC,GAAG,aAAa,CAAC,EAAE;AAAA,IAChE;AAAA,EACF;AACF;;;AV5MA,0CAAuC;AACvC,IAAAC,uBAAyC;AA2E/B,IAAAC,sBAAA;AAzEH,SAAS,wBAAwB;AACtC,QAAM,YAAY,SAAS;AAC3B,QAAwC,mBAAc,SAAS,GAAvD,kBAnBV,IAmB0C,IAAZC,WAAA,UAAY,IAAZ,CAApB;AAER,QAAM,EAAE,wBAAwB,mBAAAC,oBAAmB,gBAAAC,gBAAe,IAChE,yBAAyB;AAE3B,WAASC,iBAAgB,EAAE,SAAS,GAAsB;AACxD,UAAM,CAAC,cAAc,eAAe,QAAI,0BAAW,gBAAgB;AAAA,MACjE,SAAS;AAAA,MACT,kBAAkB,CAAC;AAAA,MACnB,aAAa,CAAC;AAAA,IAChB,CAAC;AAGD,UAAM,kBAAoC;AAAA,MACxC,CAAC;AAAA,QACC;AAAA,QACA,WAAAC;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd;AAAA,MACF,MAAM;AACJ,wBAAgB;AAAA,UACd,MAAM;AAAA,UACN,SAAS;AAAA,YACP,IAAIA;AAAA,YACJ;AAAA,YACA,QAAQ;AAAA,YACR,WAAW;AAAA,YACX;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,CAAC;AAAA,IACH;AAEA,UAAM,YAAQ,2BAAY,CAACA,eAAsB;AAC/C,sBAAgB,EAAE,MAAM,SAAS,WAAAA,WAAU,CAAC;AAAA,IAC9C,GAAG,CAAC,CAAC;AAEL,UAAM,cAAU,2BAAY,CAACA,eAAsB;AACjD,sBAAgB,EAAE,MAAM,UAAU,WAAAA,WAAU,CAAC;AAAA,IAC/C,GAAG,CAAC,CAAC;AAEL,UAAM,eAAW,2BAAY,MAAM;AACjC,sBAAgB,EAAE,MAAM,YAAY,CAAC;AAAA,IACvC,GAAG,CAAC,CAAC;AAEL,UAAM,iBAAa,2BAAY,MAAM;AACnC,sBAAgB,EAAE,MAAM,aAAa,CAAC;AAAA,IACxC,GAAG,CAAC,CAAC;AAGL,oBAAgB;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,iCAAU,MAAM;AACd,aAAO,MAAM;AACX,wBAAgB,EAAE,MAAM,aAAa,CAAC;AAAA,MACxC;AAAA,IACF,GAAG,CAAC,CAAC;AAEL,WACE,6CAAC,8DAAuB,OAAO,EAAE,MAAM,EAAE,GACvC,uDAAC,iDACC,wDAAC,0BAAuB,OAAO,cAC5B;AAAA;AAAA,MAEA,aAAa,iBAAiB,IAAI,CAAC,SAAS;AAC3C,cAAM,cAAc,aAAa,YAAY,IAAI;AACjD,cAAM;AAAA,UACJ,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,QACF,IAAI;AAGJ,YAAI,gBAAgB,eAAe;AACjC,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA,YAAY;AAAA,cACZ,WAAW;AAAA,cACX;AAAA,cACA;AAAA;AAAA,YALK;AAAA,UAMP;AAAA,QAEJ,WAAW,gBAAgB,SAAS;AAElC,gBAAM,iBACJ,aAAa,YAAY;AAC3B,gBAAM,aAAa,UAAU;AAE7B,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC,QAAQ;AAAA,cACR,YAAY;AAAA,cACZ,WAAW;AAAA,cACX;AAAA,cACA;AAAA;AAAA,YALK;AAAA,UAMP;AAAA,QAEJ,OAAO;AAEL,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA,YAAY;AAAA,cACZ,WAAW;AAAA,cACX;AAAA;AAAA,YAJK;AAAA,UAKP;AAAA,QAEJ;AAAA,MACF,CAAC;AAAA,OACH,GACF,GACF;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,SAAAJ;AAAA,IACA,iBAAAG;AAAA,IACA,mBAAAF;AAAA,IACA,gBAAAC;AAAA,EACF;AACF;;;AW3JO,IAAM,EAAE,SAAS,iBAAiB,mBAAmB,eAAe,IAAI,sBAAsB;AAG9F,SAAS,oCAAoC;AAClD,SAAO,sBAAsB;AAC/B;","names":["import_react","import_react","import_jsx_runtime","_a","BottomSheet","import_react","import_react_native","import_jsx_runtime","styles","React","import_react","overlayId","close","unmount","import_react","useCurrentOverlay","useOverlayData","overlay","import_bottom_sheet","import_jsx_runtime","overlay","useCurrentOverlay","useOverlayData","OverlayProvider","overlayId"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context/provider/index.tsx","../src/context/provider/content-overlay-controller.tsx","../src/context/provider/bottom-sheet-controller.tsx","../src/context/provider/modal-controller.tsx","../src/event.ts","../src/utils/create-use-external-events.ts","../src/utils/emitter.ts","../src/utils/random-id.ts","../src/utils/create-safe-context.ts","../src/context/context.ts","../src/context/reducer.ts","../src/utils/create-overlay-context.tsx"],"sourcesContent":["export * from \"./utils\";\nexport { overlay, OverlayProvider, useCurrentOverlay, useOverlayData } from \"./utils/create-overlay-context\";\nexport type {\n OverlayControllerComponent,\n OverlayAsyncControllerComponent,\n} from \"./context/provider/content-overlay-controller\";\nexport type { BottomSheetControllerComponent } from \"./context/provider/bottom-sheet-controller\";\nexport type { ModalControllerComponent } from \"./context/provider/modal-controller\";\n","import {\n useCallback,\n useEffect,\n useReducer,\n type PropsWithChildren,\n} from \"react\";\nimport { View } from \"react-native\";\nimport { ContentOverlayController } from \"./content-overlay-controller\";\nimport { ContentBottomSheetController } from \"./bottom-sheet-controller\";\nimport { ContentModalController } from \"./modal-controller\";\nimport { type OverlayEvent, createOverlay } from \"../../event\";\nimport { randomId } from \"../../utils/random-id\";\nimport { createOverlaySafeContext } from \"../context\";\nimport { overlayReducer } from \"../reducer\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport { BottomSheetModalProvider } from \"@gorhom/bottom-sheet\";\n\nexport function createOverlayProvider() {\n const overlayId = randomId();\n const { useOverlayEvent, ...overlay } = createOverlay(overlayId);\n\n const { OverlayContextProvider, useCurrentOverlay, useOverlayData } =\n createOverlaySafeContext();\n\n function OverlayProvider({ children }: PropsWithChildren) {\n const [overlayState, overlayDispatch] = useReducer(overlayReducer, {\n current: null,\n overlayOrderList: [],\n overlayData: {},\n });\n\n // Overlay 이벤트 핸들러들\n const overlayOpen: OverlayEvent[\"open\"] = useCallback(\n ({\n controller,\n overlayId,\n componentKey,\n overlayType = \"overlay\",\n options,\n }) => {\n overlayDispatch({\n type: \"ADD\",\n overlay: {\n id: overlayId,\n componentKey,\n isOpen: true,\n isMounted: true,\n controller: controller,\n overlayType,\n options,\n },\n });\n },\n []\n );\n\n const close = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, []);\n\n const unmount = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"REMOVE\", overlayId });\n }, []);\n\n const closeAll = useCallback(() => {\n overlayDispatch({ type: \"CLOSE_ALL\" });\n }, []);\n\n const unmountAll = useCallback(() => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n }, []);\n\n // 이벤트 리스너 등록\n useOverlayEvent({\n open: overlayOpen,\n close,\n unmount,\n closeAll,\n unmountAll,\n });\n\n useEffect(() => {\n return () => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n };\n }, []);\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <BottomSheetModalProvider>\n <OverlayContextProvider value={overlayState}>\n {children}\n\n {overlayState.overlayOrderList.map((item) => {\n const overlayItem = overlayState.overlayData[item];\n const {\n id: currentOverlayId,\n componentKey,\n isOpen,\n controller: Controller,\n overlayType,\n options,\n } = overlayItem;\n\n // 타입에 따라 다른 컨트롤러 렌더링\n if (overlayType === \"bottomSheet\") {\n return (\n <ContentBottomSheetController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else if (overlayType === \"modal\") {\n // 모달의 경우 현재 활성화된 모달만 표시\n const isCurrentModal =\n overlayState.current === currentOverlayId;\n const shouldShow = isOpen && isCurrentModal;\n\n return (\n <ContentModalController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else {\n // 기존 overlay (backward compatibility)\n return (\n <ContentOverlayController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n />\n );\n }\n })}\n </OverlayContextProvider>\n </BottomSheetModalProvider>\n </GestureHandlerRootView>\n );\n }\n\n return {\n overlay,\n OverlayProvider,\n useCurrentOverlay,\n useOverlayData,\n };\n}\n","import React, { type FC, memo, useEffect, type Dispatch } from \"react\";\nimport { Modal } from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype OverlayControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n};\n\ntype OverlayAsyncControllerProps<T> = Omit<OverlayControllerProps, \"close\"> & {\n close: (param: T) => void;\n};\n\nexport type OverlayControllerComponent = FC<OverlayControllerProps>;\nexport type OverlayAsyncControllerComponent<T> = FC<\n OverlayAsyncControllerProps<T>\n>;\n\ntype ContentOverlayControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: OverlayControllerComponent;\n};\n\nexport const ContentOverlayController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n }: ContentOverlayControllerProps) => {\n useEffect(() => {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n }, [overlayDispatch, overlayId]);\n\n return (\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n />\n );\n }\n);\n","import React, {\n type FC,\n memo,\n useEffect,\n useRef,\n type Dispatch,\n useCallback,\n useState,\n} from \"react\";\nimport BottomSheet, {\n BottomSheetModal,\n BottomSheetView,\n BottomSheetFlatList,\n BottomSheetScrollView,\n BottomSheetBackdrop,\n BottomSheetModalProvider,\n BottomSheetTextInput,\n} from \"@gorhom/bottom-sheet\";\nimport {\n StyleProp,\n ViewStyle,\n ListRenderItem,\n View,\n StyleSheet,\n Platform,\n Keyboard,\n} from \"react-native\";\nimport { useReducedMotion } from \"react-native-reanimated\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype BottomSheetControllerProps<T = any> = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Enhanced features\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n // FlatList support\n isFlatList?: boolean;\n data?: ArrayLike<T> | null | undefined;\n renderItem?: ListRenderItem<T> | null | undefined;\n keyExtractor?: ((item: T, index: number) => string) | undefined;\n contentContainerStyle?: StyleProp<ViewStyle> | undefined;\n ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;\n flatListHeader?: React.ReactNode;\n flatListFooter?: React.ReactNode;\n // Backdrop\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n onBackdropPress?: () => void;\n // Dynamic sizing\n enableDynamicSizing?: boolean;\n // Scrolling\n enableScrolling?: boolean;\n // Styling\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n // Loading & empty state\n isLoading?: boolean;\n emptyText?: string;\n extraData?: any;\n // Keyboard height (Android)\n keyboardHeight?: number;\n};\n\nexport type BottomSheetControllerComponent<T = any> = FC<\n BottomSheetControllerProps<T>\n>;\n\ntype ContentBottomSheetControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: BottomSheetControllerComponent;\n options?: {\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n enableDynamicSizing?: boolean;\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n [key: string]: any;\n };\n};\n\nexport const ContentBottomSheetController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentBottomSheetControllerProps) => {\n const bottomSheetRef = useRef<BottomSheet>(null);\n const reducedMotion = useReducedMotion();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n // --- Android keyboard handling defaults ---\n // On Android, the sheet won't move with the keyboard unless:\n // 1) Activity windowSoftInputMode = \"adjustResize\"\n // 2) bottom-sheet uses keyboardBehavior=\"extend\"\n // 3) Text inputs inside sheet use BottomSheetTextInput\n\n const {\n snapPoints,\n enablePanDownToClose = true,\n enableBackdrop = true,\n backdropOpacity = 0.5,\n enableDynamicSizing = true,\n backgroundStyle = {},\n handleStyle = {},\n keyboardBehavior = Platform.OS === \"android\" ? \"extend\" : \"interactive\",\n keyboardBlurBehavior = \"restore\",\n androidKeyboardInputMode = \"adjustResize\",\n ...restOptions\n } = options;\n\n // Android 키보드 높이 감지\n useEffect(() => {\n if (Platform.OS === \"android\") {\n const keyboardDidShowListener = Keyboard.addListener(\n \"keyboardDidShow\",\n (e) => setKeyboardHeight(e.endCoordinates.height)\n );\n const keyboardDidHideListener = Keyboard.addListener(\n \"keyboardDidHide\",\n () => setKeyboardHeight(0)\n );\n\n return () => {\n keyboardDidShowListener.remove();\n keyboardDidHideListener.remove();\n };\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n const rafId = requestAnimationFrame(() => {\n bottomSheetRef.current?.expand();\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n return () => cancelAnimationFrame(rafId);\n } else {\n bottomSheetRef.current?.close();\n }\n }, [isOpen, overlayDispatch, overlayId]);\n\n const handleClose = useCallback(() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, [overlayDispatch, overlayId]);\n\n // 백드롭 렌더링\n const renderBackdrop = useCallback(\n (props: any) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={1}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior=\"close\"\n onPress={() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }}\n />\n ),\n [backdropOpacity, keyboardHeight]\n );\n // callbacks\n const handleSheetChange = useCallback((index: number) => {\n console.log(\"handleSheetChange\", index);\n }, []);\n\n if (!isOpen) return null;\n\n return (\n <BottomSheet\n ref={bottomSheetRef}\n onChange={handleSheetChange}\n android_keyboardInputMode={androidKeyboardInputMode}\n keyboardBehavior={keyboardBehavior}\n snapPoints={enableDynamicSizing ? undefined : snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n onClose={handleClose}\n keyboardBlurBehavior={keyboardBlurBehavior}\n index={0}\n backdropComponent={enableBackdrop ? renderBackdrop : undefined}\n backgroundStyle={[\n {\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n backgroundStyle,\n ]}\n handleStyle={[\n {\n backgroundColor: \"transparent\",\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n handleStyle,\n ]}\n enableDynamicSizing={enableDynamicSizing}\n animateOnMount={!reducedMotion}\n >\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n snapPoints={snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n keyboardHeight={keyboardHeight}\n {...restOptions}\n />\n </BottomSheet>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n contentContainer: {\n flex: 1,\n },\n});\n","import React, { type FC, memo, useEffect, useState } from \"react\";\nimport {\n Modal,\n View,\n TouchableWithoutFeedback,\n Animated,\n StyleSheet,\n Dimensions,\n Pressable,\n} from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype ModalControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n\nexport type ModalControllerComponent<T = {}> = FC<ModalControllerProps & T>;\n\ntype ContentModalControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: React.Dispatch<OverlayReducerAction>;\n controller: ModalControllerComponent | React.ReactElement;\n options?: {\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n };\n};\n\nconst { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get(\"window\");\n\nexport const ContentModalController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentModalControllerProps) => {\n const {\n modalType = \"center\",\n backdropOpacity = 0.5,\n animationType = \"fade\",\n swipeDirection,\n } = options;\n\n const [backdropAnimation] = useState(new Animated.Value(0));\n const [contentAnimation] = useState(new Animated.Value(0));\n\n useEffect(() => {\n if (isOpen) {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n\n // 애니메이션 시작\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n ]).start();\n } else {\n // 닫기 애니메이션\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start();\n }\n }, [\n isOpen,\n overlayDispatch,\n overlayId,\n backdropAnimation,\n contentAnimation,\n ]);\n\n const handleClose = () => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n };\n\n const getContainerStyle = () => {\n switch (modalType) {\n case \"bottom\":\n return styles.bottomContainer;\n case \"top\":\n return styles.topContainer;\n case \"left\":\n return styles.leftContainer;\n case \"right\":\n return styles.rightContainer;\n default: // center\n return styles.centerContainer;\n }\n };\n\n const getContentAnimationStyle = () => {\n const baseOpacity = {\n opacity: contentAnimation,\n };\n\n switch (modalType) {\n case \"bottom\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"top\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"left\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n case \"right\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n default: // center\n if (animationType === \"slide\") {\n return {\n ...baseOpacity,\n transform: [\n {\n scale: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [0.8, 1],\n }),\n },\n ],\n };\n }\n return baseOpacity;\n }\n };\n\n // Modal 대신 절대 위치 View 사용 (필요시)\n if (!isOpen) return null;\n\n return (\n <Modal\n visible={isOpen}\n transparent={true}\n animationType=\"none\"\n onRequestClose={handleClose}\n statusBarTranslucent={true}\n presentationStyle=\"overFullScreen\"\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={handleClose}>\n <Animated.View\n style={[\n styles.backdrop,\n {\n backgroundColor: `rgba(0, 0, 0, ${backdropOpacity})`,\n opacity: backdropAnimation,\n },\n ]}\n >\n <View style={StyleSheet.absoluteFill} pointerEvents=\"box-none\">\n <Animated.View\n style={[getContainerStyle(), getContentAnimationStyle()]}\n pointerEvents=\"box-none\"\n >\n <Pressable onPress={() => {}}>\n {React.isValidElement(Controller)\n ? React.cloneElement(\n Controller as React.ReactElement<any>,\n {\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n }\n )\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n modalType,\n backdropOpacity,\n animationType,\n swipeDirection,\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n })}\n </Pressable>\n </Animated.View>\n </View>\n </Animated.View>\n </Pressable>\n </Modal>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n backdrop: {\n ...StyleSheet.absoluteFillObject,\n },\n centerContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n },\n bottomContainer: {\n flex: 1,\n justifyContent: \"flex-end\",\n },\n topContainer: {\n flex: 1,\n justifyContent: \"flex-start\",\n },\n leftContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n },\n rightContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-end\",\n },\n});\n","// 사용자가 실제로 사용하는 API 를 만드는 팩토리\n// overlay.open(), overlay.close 등\n\nimport React from \"react\";\nimport {\n OverlayAsyncControllerComponent,\n OverlayControllerComponent,\n} from \"./context/provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./context/provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./context/provider/modal-controller\";\nimport { createUseExternalEvents } from \"./utils/create-use-external-events\";\nimport { randomId } from \"./utils/random-id\";\n\nexport type OverlayEvent = {\n open: (args: {\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement;\n overlayId: string;\n componentKey: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n options?: any;\n }) => void;\n close: (overlayId: string) => void;\n unmount: (overlayId: string) => void;\n closeAll: () => void;\n unmountAll: () => void;\n};\n\ntype OpenOverlayOptions = {\n overlayId?: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n // BottomSheet options\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Modal options\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n enableDynamicSizing?: boolean;\n animationType?:\n | \"none\"\n | \"slide\"\n | \"fade\"\n | \"bounceIn\"\n | \"bounceInDown\"\n | \"bounceInUp\"\n | \"bounceInLeft\"\n | \"bounceInRight\"\n | \"bounceOut\"\n | \"bounceOutDown\"\n | \"bounceOutUp\"\n | \"bounceOutLeft\"\n | \"bounceOutRight\"\n | \"fadeIn\"\n | \"fadeInDown\"\n | \"fadeInDownBig\"\n | \"fadeInUp\"\n | \"fadeInUpBig\"\n | \"fadeInLeft\"\n | \"fadeInLeftBig\"\n | \"fadeInRight\"\n | \"fadeInRightBig\"\n | \"fadeOut\"\n | \"fadeOutDown\"\n | \"fadeOutDownBig\"\n | \"fadeOutUp\"\n | \"fadeOutUpBig\"\n | \"fadeOutLeft\"\n | \"fadeOutLeftBig\"\n | \"fadeOutRight\"\n | \"fadeOutRightBig\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n// id 받아\nexport function createOverlay(overlayId: string) {\n const [useOverlayEvent, createEvent] = createUseExternalEvents<OverlayEvent>(\n `${overlayId}/overlay-kit`\n );\n\n const open = (\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement,\n options?: OpenOverlayOptions\n ) => {\n const overlayId = options?.overlayId ?? randomId();\n const componentKey = randomId();\n const overlayType = options?.overlayType ?? \"overlay\";\n\n const dispatchOpenEvent = createEvent(\"open\");\n\n // 옵션에서 overlayType과 overlayId를 제외한 나머지를 options로 전달\n const { overlayId: _, overlayType: __, ...restOptions } = options || {};\n\n // JSX 엘리먼트인 경우 wrapper 컴포넌트로 감싸기\n let finalController;\n if (React.isValidElement(controller)) {\n finalController = (props: any) => {\n return React.cloneElement(controller as React.ReactElement, {\n ...(controller.props || {}),\n ...props,\n close: props.close,\n unmount: props.unmount,\n });\n };\n } else {\n finalController = controller;\n }\n\n dispatchOpenEvent({\n controller: finalController,\n overlayId,\n componentKey,\n overlayType,\n options: restOptions,\n });\n return overlayId;\n };\n\n // openAsync는 모든 overlay 타입에서 사용 가능\n const openAsync = async <T>(\n controller:\n | OverlayAsyncControllerComponent<T>\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | ((props: any) => any),\n options?: OpenOverlayOptions\n ) => {\n return new Promise<T>((resolve) => {\n const wrappedController = (overlayProps: any) => {\n const close = (param?: T) => {\n resolve(param as T);\n overlayProps.close();\n };\n const unmount = (param?: T) => {\n resolve(param as T);\n overlayProps.unmount();\n };\n const props = { ...overlayProps, close, unmount };\n return controller(props);\n };\n\n open(wrappedController, options);\n });\n };\n const close = createEvent(\"close\");\n const unmount = createEvent(\"unmount\");\n const closeAll = createEvent(\"closeAll\");\n const unmountAll = createEvent(\"unmountAll\");\n return {\n open,\n openAsync,\n close,\n unmount,\n closeAll,\n unmountAll,\n useOverlayEvent,\n };\n}\n","import { useEffect } from \"react\";\nimport { createEmitter } from \"./emitter\";\n\nconst emitter = createEmitter();\n\n// React Native에서는 useEffect를 사용 (useLayoutEffect 대신)\nfunction useClientEffect(...args: Parameters<typeof useEffect>) {\n // RN에서는 항상 useEffect 실행\n useEffect(...args);\n}\n\n// 단순한 wrapper 함수\n// emitter.emit을 한번 감싼 이유는 나중에 로깅, 디버깅 등 추가 기능을 넣기 위함\nfunction dispatchEvent<Detail>(type: string, detail?: Detail) {\n emitter.emit(type, detail);\n}\n\n// 메인 팩토리 함수\n// 사용 예\n// createUseExternalEvents<OverlayEvents>('overlay-kit')\n// prefix의 역할:\n// - 'overlay-kit' → 실제 이벤트명은 overlay-kit:open, overlay-kit:close\n// - 네임스페이스로 이벤트 충돌 방지\n\nfunction createUseExternalEvents<\n EventHandlers extends Record<string, (params: any) => void>\n>(prefix: string) {\n function useExternalEvents(events: EventHandlers) {\n // 변환 과정:\n // 입력:\n // events = {\n // open: (data) => console.log('열기', data),\n // close: (id) => console.log('닫기', id)\n // }\n\n // 변환 결과:\n // handlers = {\n // 'overlay-kit:open': (event) => events.open(event),\n // 'overlay-kit:close': (event) => events.close(event)\n // }\n\n const handlers = Object.keys(events).reduce<Record<string, () => void>>(\n (prev, eventKey) => {\n const currentEventKeys = `${prefix}:${eventKey}`;\n\n return {\n ...prev,\n [currentEventKeys]: function (event: unknown) {\n events[eventKey](event);\n } as () => void,\n };\n },\n {}\n );\n\n useClientEffect(() => {\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]); // 🔥 기존 핸들러 제거\n // (중복 방지)\n emitter.on(eventKey, handlers[eventKey]); // 🔥 새로운 핸들러 등록\n });\n\n // 🧹 컴포넌트 언마운트시 정리\n return () =>\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]);\n });\n }, [handlers]);\n }\n\n // 타입 분석:\n // EventKey = 'open' | 'close' | 'closeAll'\n // Parameters<EventHandlers['open']> = [data: {component: Component, id:\n // string}]\n\n // const openEvent = createEvent('open');\n // openEvent의 타입: (data: {component: Component, id: string}) => void\n\n // openEvent({component: MyModal, id: '123'});\n // → dispatchEvent('overlay-kit:open', {component: MyModal, id: '123'})\n\n // payload[0]을 사용하는 이유:\n // 함수 호출: openEvent(arg1, arg2, arg3)\n // payload = [arg1, arg2, arg3]\n // payload[0] = arg1 (첫 번째 인자만 이벤트 데이터로 전달)\n\n function createEvent<EventKey extends keyof EventHandlers>(event: EventKey) {\n return (...payload: Parameters<EventHandlers[EventKey]>) =>\n dispatchEvent(`${prefix}:${String(event)}`, payload[0]);\n }\n\n return [useExternalEvents, createEvent] as const;\n}\n\n// 💡 이 패턴의 천재적인 점\n\n// 1. React 외부에서 React 내부 제어: overlay.open() 같은 명령형 API 가능\n// 2. 타입 안전성: TypeScript로 이벤트 타입 완벽 추론\n// 3. 메모리 안전: React Hook 생명주기와 완벽 동기화\n// 4. 플랫폼 호환: 웹/RN 모두 지원\n// 5. 네임스페이스: 이벤트 충돌 방지\n\nexport { createUseExternalEvents };\n","\n// 이벤트 이름\nexport type EventType = string | symbol;\n\n// 이벤트 핸들러\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;\n\n// 이벤트 핸들러 목록\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;\n\n// 이벤트 핸들러 맵\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | '*',\n EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\n// 이벤트 발행기\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n all: EventHandlerMap<Events>;\n\n on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n on(type: '*', handler: WildcardHandler<Events>): void;\n\n off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;\n off(type: '*', handler: WildcardHandler<Events>): void;\n\n emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;\n}\n\nexport function createEmitter<Events extends Record<EventType, unknown>>(\n all?: EventHandlerMap<Events>\n): Emitter<Events> {\n type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>;\n all = all || new Map();\n\n return {\n all,\n on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n handlers.push(handler);\n } else {\n all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n }\n },\n off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n all!.set(type, []);\n }\n }\n },\n emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n let handlers = all!.get(type);\n if (handlers) {\n (handlers as EventHandlerList<Events[keyof Events]>).slice().forEach((handler) => {\n handler(evt!);\n });\n }\n\n handlers = all!.get('*');\n if (handlers) {\n (handlers as WildCardEventHandlerList<Events>).slice().forEach((handler) => {\n handler(type, evt!);\n });\n }\n },\n };\n}","export function randomId() {\n return `overlay-kit-${Math.random().toString(36).slice(2, 11)}`;\n}","import { type Provider, createContext, useContext } from 'react';\n\ntype NullSymbolType = typeof NullSymbol;\nconst NullSymbol = Symbol('Null');\n\nexport type CreateContextReturn<T> = [Provider<T>, () => T];\n\nexport function createSafeContext<T>(displayName?: string): CreateContextReturn<T> {\n const Context = createContext<T | NullSymbolType>(NullSymbol);\n Context.displayName = displayName ?? 'SafeContext';\n\n function useSafeContext() {\n const context = useContext(Context);\n\n if (context === NullSymbol) {\n const error = new Error(`[${Context.displayName}]: Provider not found.`);\n error.name = '[Error] Context';\n\n throw error;\n }\n\n return context;\n }\n\n return [Context.Provider as any, useSafeContext];\n}\n","import { createSafeContext } from '../utils/create-safe-context';\nimport { type OverlayData } from './reducer';\n\n\nexport function createOverlaySafeContext() {\n const [OverlayContextProvider, useOverlayContext] = createSafeContext<OverlayData>('overlay-kit/OverlayContext');\n\n function useCurrentOverlay() {\n return useOverlayContext().current;\n }\n\n function useOverlayData() {\n return useOverlayContext().overlayData;\n }\n\n return { OverlayContextProvider, useCurrentOverlay, useOverlayData };\n}\n","import { OverlayControllerComponent } from \"./provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./provider/modal-controller\";\n\ntype OverlayId = string;\ntype OverlayItem = {\n /**\n * @description 오버레이 고유한 ID\n */\n id : OverlayId;\n /**\n * @description 오버레이 컴포넌트의 고유한 키\n * 컴포넌트가 언마운트시 사용됩니다.\n */\n componentKey: string;\n isOpen: boolean;\n isMounted: boolean;\n controller: OverlayControllerComponent | BottomSheetControllerComponent | ModalControllerComponent;\n overlayType?: 'overlay' | 'bottomSheet' | 'modal';\n options?: any;\n}\nexport type OverlayData = {\n current: OverlayId | null; // 현재 열려있는 오버레이 ID\n overlayOrderList: OverlayId[];\n overlayData: Record<OverlayId, OverlayItem>;\n}\nexport type OverlayReducerAction =\n | { type: 'ADD'; overlay: OverlayItem }\n | { type: 'OPEN'; overlayId: string }\n | { type: 'CLOSE'; overlayId: string }\n | { type: 'REMOVE'; overlayId: string }\n | { type: 'CLOSE_ALL' }\n | { type: 'REMOVE_ALL' };\n\n/**\n * 오버레이를 닫거나 제거할 때, 어떤 오버레이를 현재(current)로 지정할지 결정합니다.\n *\n * @description 마지막 오버레이를 닫을 경우, 그 이전 오버레이를 현재로 지정합니다.\n * @description 중간에 있는 오버레이를 닫을 경우, 마지막 오버레이를 현재로 지정합니다.\n *\n * @example open - [1, 2, 3, 4]\n * close 2 => current: 4\n * close 4 => current: 3\n * close 3 => current: 1\n * close 1 => current: null\n *\n * @param overlayOrderList 오버레이 ID가 순서대로 담긴 리스트\n * @param overlayData 오버레이 데이터 맵\n * @param targetOverlayId 닫거나 제거하려는 오버레이의 ID\n * @returns 현재로 지정될 오버레이의 ID, 없으면 null\n */\nexport const determineCurrentOverlayId = (overlayOrderList: OverlayId[], overlayData: Record<OverlayId, OverlayItem>, targetOverlayId: OverlayId): OverlayId | null => {\n // 1단계: 열린 오버레이들만 필터링\n\n const openedOverlayOrderList = overlayOrderList.filter(\n (orderedOverlayId) => overlayData[orderedOverlayId].isOpen === true\n );\n // 2단계: 닫힐 오버레이의 위치 찾기\n const targetIndexInOpenedList = openedOverlayOrderList.findIndex((item) => item === targetOverlayId);\n\n // 3단계: 다음 활성 오버레이 결정\n return targetIndexInOpenedList === openedOverlayOrderList.length - 1\n ? openedOverlayOrderList[targetIndexInOpenedList - 1] ?? null // 마지막이면 이전 것\n : openedOverlayOrderList[openedOverlayOrderList.length - 1] ?? null;// 중간이면 최상위\n\n}\n\n/** 동작 예시:\n * \n *\n * // 상황: 오버레이 [1, 2, 3, 4]가 순서대로 열려있음\n * overlayOrderList = [\"modal-1\", \"modal-2\", \"modal-3\", \"modal-4\"];\n * // 모두 isOpen: true\n *\n * // 케이스 1: 최상위(4번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-4\");\n * // → \"modal-3\" (바로 아래가 활성화)\n *\n * // 케이스 2: 중간(2번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-2\");\n * // → \"modal-4\" (최상위가 여전히 활성)\n *\n * // 케이스 3: 마지막 남은 것 닫기\n * determineCurrentOverlayId([\"modal-1\"], data, \"modal-1\");\n * // → null (더 이상 활성 오버레이 없음)\n */\n\n// 상태 변경 로직\nexport function overlayReducer(state: OverlayData, action: OverlayReducerAction): OverlayData {\n switch (action.type) {\n case 'ADD': {\n if (state.overlayData[action.overlay.id] != null && state.overlayData[action.overlay.id].isOpen === false) {\n const overlay = state.overlayData[action.overlay.id];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n current: action.overlay.id,\n overlayData: {\n ...state.overlayData,\n [action.overlay.id]: { ...overlay, isOpen: true },\n },\n };\n }\n\n const isExisted = state.overlayOrderList.includes(action.overlay.id);\n\n if (isExisted && state.overlayData[action.overlay.id].isOpen === true) {\n throw new Error(\n `You can't open the multiple overlays with the same overlayId(${action.overlay.id}). Please set a different id.`\n );\n }\n\n return {\n current: action.overlay.id,\n /**\n * @description Brings the overlay to the front when reopened after closing without unmounting.\n */\n overlayOrderList: [...state.overlayOrderList.filter((item) => item !== action.overlay.id), action.overlay.id],\n overlayData: isExisted\n ? state.overlayData\n : {\n ...state.overlayData,\n [action.overlay.id]: action.overlay,\n },\n };\n }\n case 'OPEN': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: { ...overlay, isOpen: true, isMounted: true },\n },\n };\n }\n case 'CLOSE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already closed\n if (overlay == null || !overlay.isOpen) {\n return state;\n }\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n ...state,\n current: currentOverlayId,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: {\n ...state.overlayData[action.overlayId],\n isOpen: false,\n },\n },\n };\n }\n case 'REMOVE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist\n if (overlay == null) {\n return state;\n }\n\n const remainingOverlays = state.overlayOrderList.filter((item) => item !== action.overlayId);\n if (state.overlayOrderList.length === remainingOverlays.length) {\n return state;\n }\n\n const copiedOverlayData = { ...state.overlayData };\n delete copiedOverlayData[action.overlayId];\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n current: currentOverlayId,\n overlayOrderList: remainingOverlays,\n overlayData: copiedOverlayData,\n };\n }\n case 'CLOSE_ALL': {\n // ignore if there is no overlay\n if (Object.keys(state.overlayData).length === 0) {\n return state;\n }\n\n return {\n ...state,\n current: null,\n overlayData: Object.keys(state.overlayData).reduce(\n (prev, curr) => ({\n ...prev,\n [curr]: {\n ...state.overlayData[curr],\n isOpen: false,\n } satisfies OverlayItem,\n }),\n {} satisfies Record<string, OverlayItem>\n ),\n };\n }\n case 'REMOVE_ALL': {\n return { current: null, overlayOrderList: [], overlayData: {} };\n }\n }\n}","import { createOverlayProvider } from '../context/provider';\n\nexport const { overlay, OverlayProvider, useCurrentOverlay, useOverlayData } = createOverlayProvider();\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function experimental_createOverlayContext() {\n return createOverlayProvider();\n}"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","_a","BottomSheet","import_react","import_react_native","import_jsx_runtime","styles","React","import_react","import_react","overlayId","React","close","unmount","import_react","useCurrentOverlay","useOverlayData","overlay","import_bottom_sheet","import_jsx_runtime","overlay","useCurrentOverlay","useOverlayData","OverlayProvider","overlayId"]}
|
package/dist/index.mjs
CHANGED
|
@@ -445,6 +445,9 @@ var styles2 = StyleSheet2.create({
|
|
|
445
445
|
}
|
|
446
446
|
});
|
|
447
447
|
|
|
448
|
+
// src/event.ts
|
|
449
|
+
import React4 from "react";
|
|
450
|
+
|
|
448
451
|
// src/utils/create-use-external-events.ts
|
|
449
452
|
import { useEffect as useEffect4 } from "react";
|
|
450
453
|
|
|
@@ -542,8 +545,19 @@ function createOverlay(overlayId) {
|
|
|
542
545
|
const overlayType = (_b = options == null ? void 0 : options.overlayType) != null ? _b : "overlay";
|
|
543
546
|
const dispatchOpenEvent = createEvent("open");
|
|
544
547
|
const _c = options || {}, { overlayId: _, overlayType: __ } = _c, restOptions = __objRest(_c, ["overlayId", "overlayType"]);
|
|
548
|
+
let finalController;
|
|
549
|
+
if (React4.isValidElement(controller)) {
|
|
550
|
+
finalController = (props) => {
|
|
551
|
+
return React4.cloneElement(controller, __spreadProps(__spreadValues(__spreadValues({}, controller.props || {}), props), {
|
|
552
|
+
close: props.close,
|
|
553
|
+
unmount: props.unmount
|
|
554
|
+
}));
|
|
555
|
+
};
|
|
556
|
+
} else {
|
|
557
|
+
finalController = controller;
|
|
558
|
+
}
|
|
545
559
|
dispatchOpenEvent({
|
|
546
|
-
controller,
|
|
560
|
+
controller: finalController,
|
|
547
561
|
overlayId: overlayId2,
|
|
548
562
|
componentKey,
|
|
549
563
|
overlayType,
|
|
@@ -553,7 +567,7 @@ function createOverlay(overlayId) {
|
|
|
553
567
|
};
|
|
554
568
|
const openAsync = async (controller, options) => {
|
|
555
569
|
return new Promise((resolve) => {
|
|
556
|
-
const wrappedController = (overlayProps
|
|
570
|
+
const wrappedController = (overlayProps) => {
|
|
557
571
|
const close2 = (param) => {
|
|
558
572
|
resolve(param);
|
|
559
573
|
overlayProps.close();
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/provider/index.tsx","../src/context/provider/content-overlay-controller.tsx","../src/context/provider/bottom-sheet-controller.tsx","../src/context/provider/modal-controller.tsx","../src/utils/create-use-external-events.ts","../src/utils/emitter.ts","../src/utils/random-id.ts","../src/event.ts","../src/utils/create-safe-context.ts","../src/context/context.ts","../src/context/reducer.ts","../src/utils/create-overlay-context.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useReducer,\n type PropsWithChildren,\n} from \"react\";\nimport { View } from \"react-native\";\nimport { ContentOverlayController } from \"./content-overlay-controller\";\nimport { ContentBottomSheetController } from \"./bottom-sheet-controller\";\nimport { ContentModalController } from \"./modal-controller\";\nimport { type OverlayEvent, createOverlay } from \"../../event\";\nimport { randomId } from \"../../utils/random-id\";\nimport { createOverlaySafeContext } from \"../context\";\nimport { overlayReducer } from \"../reducer\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport { BottomSheetModalProvider } from \"@gorhom/bottom-sheet\";\n\nexport function createOverlayProvider() {\n const overlayId = randomId();\n const { useOverlayEvent, ...overlay } = createOverlay(overlayId);\n\n const { OverlayContextProvider, useCurrentOverlay, useOverlayData } =\n createOverlaySafeContext();\n\n function OverlayProvider({ children }: PropsWithChildren) {\n const [overlayState, overlayDispatch] = useReducer(overlayReducer, {\n current: null,\n overlayOrderList: [],\n overlayData: {},\n });\n\n // Overlay 이벤트 핸들러들\n const overlayOpen: OverlayEvent[\"open\"] = useCallback(\n ({\n controller,\n overlayId,\n componentKey,\n overlayType = \"overlay\",\n options,\n }) => {\n overlayDispatch({\n type: \"ADD\",\n overlay: {\n id: overlayId,\n componentKey,\n isOpen: true,\n isMounted: true,\n controller: controller,\n overlayType,\n options,\n },\n });\n },\n []\n );\n\n const close = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, []);\n\n const unmount = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"REMOVE\", overlayId });\n }, []);\n\n const closeAll = useCallback(() => {\n overlayDispatch({ type: \"CLOSE_ALL\" });\n }, []);\n\n const unmountAll = useCallback(() => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n }, []);\n\n // 이벤트 리스너 등록\n useOverlayEvent({\n open: overlayOpen,\n close,\n unmount,\n closeAll,\n unmountAll,\n });\n\n useEffect(() => {\n return () => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n };\n }, []);\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <BottomSheetModalProvider>\n <OverlayContextProvider value={overlayState}>\n {children}\n\n {overlayState.overlayOrderList.map((item) => {\n const overlayItem = overlayState.overlayData[item];\n const {\n id: currentOverlayId,\n componentKey,\n isOpen,\n controller: Controller,\n overlayType,\n options,\n } = overlayItem;\n\n // 타입에 따라 다른 컨트롤러 렌더링\n if (overlayType === \"bottomSheet\") {\n return (\n <ContentBottomSheetController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else if (overlayType === \"modal\") {\n // 모달의 경우 현재 활성화된 모달만 표시\n const isCurrentModal =\n overlayState.current === currentOverlayId;\n const shouldShow = isOpen && isCurrentModal;\n\n return (\n <ContentModalController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else {\n // 기존 overlay (backward compatibility)\n return (\n <ContentOverlayController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n />\n );\n }\n })}\n </OverlayContextProvider>\n </BottomSheetModalProvider>\n </GestureHandlerRootView>\n );\n }\n\n return {\n overlay,\n OverlayProvider,\n useCurrentOverlay,\n useOverlayData,\n };\n}\n","import React, { type FC, memo, useEffect, type Dispatch } from \"react\";\nimport { Modal } from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype OverlayControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n};\n\ntype OverlayAsyncControllerProps<T> = Omit<OverlayControllerProps, \"close\"> & {\n close: (param: T) => void;\n};\n\nexport type OverlayControllerComponent = FC<OverlayControllerProps>;\nexport type OverlayAsyncControllerComponent<T> = FC<\n OverlayAsyncControllerProps<T>\n>;\n\ntype ContentOverlayControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: OverlayControllerComponent;\n};\n\nexport const ContentOverlayController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n }: ContentOverlayControllerProps) => {\n useEffect(() => {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n }, [overlayDispatch, overlayId]);\n\n return (\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n />\n );\n }\n);\n","import React, {\n type FC,\n memo,\n useEffect,\n useRef,\n type Dispatch,\n useCallback,\n useState,\n} from \"react\";\nimport BottomSheet, {\n BottomSheetModal,\n BottomSheetView,\n BottomSheetFlatList,\n BottomSheetScrollView,\n BottomSheetBackdrop,\n BottomSheetModalProvider,\n BottomSheetTextInput,\n} from \"@gorhom/bottom-sheet\";\nimport {\n StyleProp,\n ViewStyle,\n ListRenderItem,\n View,\n StyleSheet,\n Platform,\n Keyboard,\n} from \"react-native\";\nimport { useReducedMotion } from \"react-native-reanimated\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype BottomSheetControllerProps<T = any> = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Enhanced features\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n // FlatList support\n isFlatList?: boolean;\n data?: ArrayLike<T> | null | undefined;\n renderItem?: ListRenderItem<T> | null | undefined;\n keyExtractor?: ((item: T, index: number) => string) | undefined;\n contentContainerStyle?: StyleProp<ViewStyle> | undefined;\n ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;\n flatListHeader?: React.ReactNode;\n flatListFooter?: React.ReactNode;\n // Backdrop\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n onBackdropPress?: () => void;\n // Dynamic sizing\n enableDynamicSizing?: boolean;\n // Scrolling\n enableScrolling?: boolean;\n // Styling\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n // Loading & empty state\n isLoading?: boolean;\n emptyText?: string;\n extraData?: any;\n // Keyboard height (Android)\n keyboardHeight?: number;\n};\n\nexport type BottomSheetControllerComponent<T = any> = FC<\n BottomSheetControllerProps<T>\n>;\n\ntype ContentBottomSheetControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: BottomSheetControllerComponent;\n options?: {\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n enableDynamicSizing?: boolean;\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n [key: string]: any;\n };\n};\n\nexport const ContentBottomSheetController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentBottomSheetControllerProps) => {\n const bottomSheetRef = useRef<BottomSheet>(null);\n const reducedMotion = useReducedMotion();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n // --- Android keyboard handling defaults ---\n // On Android, the sheet won't move with the keyboard unless:\n // 1) Activity windowSoftInputMode = \"adjustResize\"\n // 2) bottom-sheet uses keyboardBehavior=\"extend\"\n // 3) Text inputs inside sheet use BottomSheetTextInput\n\n const {\n snapPoints,\n enablePanDownToClose = true,\n enableBackdrop = true,\n backdropOpacity = 0.5,\n enableDynamicSizing = true,\n backgroundStyle = {},\n handleStyle = {},\n keyboardBehavior = Platform.OS === \"android\" ? \"extend\" : \"interactive\",\n keyboardBlurBehavior = \"restore\",\n androidKeyboardInputMode = \"adjustResize\",\n ...restOptions\n } = options;\n\n // Android 키보드 높이 감지\n useEffect(() => {\n if (Platform.OS === \"android\") {\n const keyboardDidShowListener = Keyboard.addListener(\n \"keyboardDidShow\",\n (e) => setKeyboardHeight(e.endCoordinates.height)\n );\n const keyboardDidHideListener = Keyboard.addListener(\n \"keyboardDidHide\",\n () => setKeyboardHeight(0)\n );\n\n return () => {\n keyboardDidShowListener.remove();\n keyboardDidHideListener.remove();\n };\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n const rafId = requestAnimationFrame(() => {\n bottomSheetRef.current?.expand();\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n return () => cancelAnimationFrame(rafId);\n } else {\n bottomSheetRef.current?.close();\n }\n }, [isOpen, overlayDispatch, overlayId]);\n\n const handleClose = useCallback(() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, [overlayDispatch, overlayId]);\n\n // 백드롭 렌더링\n const renderBackdrop = useCallback(\n (props: any) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={1}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior=\"close\"\n onPress={() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }}\n />\n ),\n [backdropOpacity, keyboardHeight]\n );\n // callbacks\n const handleSheetChange = useCallback((index: number) => {\n console.log(\"handleSheetChange\", index);\n }, []);\n\n if (!isOpen) return null;\n\n return (\n <BottomSheet\n ref={bottomSheetRef}\n onChange={handleSheetChange}\n android_keyboardInputMode={androidKeyboardInputMode}\n keyboardBehavior={keyboardBehavior}\n snapPoints={enableDynamicSizing ? undefined : snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n onClose={handleClose}\n keyboardBlurBehavior={keyboardBlurBehavior}\n index={0}\n backdropComponent={enableBackdrop ? renderBackdrop : undefined}\n backgroundStyle={[\n {\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n backgroundStyle,\n ]}\n handleStyle={[\n {\n backgroundColor: \"transparent\",\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n handleStyle,\n ]}\n enableDynamicSizing={enableDynamicSizing}\n animateOnMount={!reducedMotion}\n >\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n snapPoints={snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n keyboardHeight={keyboardHeight}\n {...restOptions}\n />\n </BottomSheet>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n contentContainer: {\n flex: 1,\n },\n});\n","import React, { type FC, memo, useEffect, useState } from \"react\";\nimport {\n Modal,\n View,\n TouchableWithoutFeedback,\n Animated,\n StyleSheet,\n Dimensions,\n Pressable,\n} from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype ModalControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n\nexport type ModalControllerComponent<T = {}> = FC<ModalControllerProps & T>;\n\ntype ContentModalControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: React.Dispatch<OverlayReducerAction>;\n controller: ModalControllerComponent | React.ReactElement;\n options?: {\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n };\n};\n\nconst { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get(\"window\");\n\nexport const ContentModalController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentModalControllerProps) => {\n const {\n modalType = \"center\",\n backdropOpacity = 0.5,\n animationType = \"fade\",\n swipeDirection,\n } = options;\n\n const [backdropAnimation] = useState(new Animated.Value(0));\n const [contentAnimation] = useState(new Animated.Value(0));\n\n useEffect(() => {\n if (isOpen) {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n\n // 애니메이션 시작\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n ]).start();\n } else {\n // 닫기 애니메이션\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start();\n }\n }, [\n isOpen,\n overlayDispatch,\n overlayId,\n backdropAnimation,\n contentAnimation,\n ]);\n\n const handleClose = () => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n };\n\n const getContainerStyle = () => {\n switch (modalType) {\n case \"bottom\":\n return styles.bottomContainer;\n case \"top\":\n return styles.topContainer;\n case \"left\":\n return styles.leftContainer;\n case \"right\":\n return styles.rightContainer;\n default: // center\n return styles.centerContainer;\n }\n };\n\n const getContentAnimationStyle = () => {\n const baseOpacity = {\n opacity: contentAnimation,\n };\n\n switch (modalType) {\n case \"bottom\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"top\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"left\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n case \"right\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n default: // center\n if (animationType === \"slide\") {\n return {\n ...baseOpacity,\n transform: [\n {\n scale: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [0.8, 1],\n }),\n },\n ],\n };\n }\n return baseOpacity;\n }\n };\n\n // Modal 대신 절대 위치 View 사용 (필요시)\n if (!isOpen) return null;\n\n return (\n <Modal\n visible={isOpen}\n transparent={true}\n animationType=\"none\"\n onRequestClose={handleClose}\n statusBarTranslucent={true}\n presentationStyle=\"overFullScreen\"\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={handleClose}>\n <Animated.View\n style={[\n styles.backdrop,\n {\n backgroundColor: `rgba(0, 0, 0, ${backdropOpacity})`,\n opacity: backdropAnimation,\n },\n ]}\n >\n <View style={StyleSheet.absoluteFill} pointerEvents=\"box-none\">\n <Animated.View\n style={[getContainerStyle(), getContentAnimationStyle()]}\n pointerEvents=\"box-none\"\n >\n <Pressable onPress={() => {}}>\n {React.isValidElement(Controller)\n ? React.cloneElement(\n Controller as React.ReactElement<any>,\n {\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n }\n )\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n modalType,\n backdropOpacity,\n animationType,\n swipeDirection,\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n })}\n </Pressable>\n </Animated.View>\n </View>\n </Animated.View>\n </Pressable>\n </Modal>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n backdrop: {\n ...StyleSheet.absoluteFillObject,\n },\n centerContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n },\n bottomContainer: {\n flex: 1,\n justifyContent: \"flex-end\",\n },\n topContainer: {\n flex: 1,\n justifyContent: \"flex-start\",\n },\n leftContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n },\n rightContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-end\",\n },\n});\n","import { useEffect } from \"react\";\nimport { createEmitter } from \"./emitter\";\n\nconst emitter = createEmitter();\n\n// React Native에서는 useEffect를 사용 (useLayoutEffect 대신)\nfunction useClientEffect(...args: Parameters<typeof useEffect>) {\n // RN에서는 항상 useEffect 실행\n useEffect(...args);\n}\n\n// 단순한 wrapper 함수\n// emitter.emit을 한번 감싼 이유는 나중에 로깅, 디버깅 등 추가 기능을 넣기 위함\nfunction dispatchEvent<Detail>(type: string, detail?: Detail) {\n emitter.emit(type, detail);\n}\n\n// 메인 팩토리 함수\n// 사용 예\n// createUseExternalEvents<OverlayEvents>('overlay-kit')\n// prefix의 역할:\n// - 'overlay-kit' → 실제 이벤트명은 overlay-kit:open, overlay-kit:close\n// - 네임스페이스로 이벤트 충돌 방지\n\nfunction createUseExternalEvents<\n EventHandlers extends Record<string, (params: any) => void>\n>(prefix: string) {\n function useExternalEvents(events: EventHandlers) {\n // 변환 과정:\n // 입력:\n // events = {\n // open: (data) => console.log('열기', data),\n // close: (id) => console.log('닫기', id)\n // }\n\n // 변환 결과:\n // handlers = {\n // 'overlay-kit:open': (event) => events.open(event),\n // 'overlay-kit:close': (event) => events.close(event)\n // }\n\n const handlers = Object.keys(events).reduce<Record<string, () => void>>(\n (prev, eventKey) => {\n const currentEventKeys = `${prefix}:${eventKey}`;\n\n return {\n ...prev,\n [currentEventKeys]: function (event: unknown) {\n events[eventKey](event);\n } as () => void,\n };\n },\n {}\n );\n\n useClientEffect(() => {\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]); // 🔥 기존 핸들러 제거\n // (중복 방지)\n emitter.on(eventKey, handlers[eventKey]); // 🔥 새로운 핸들러 등록\n });\n\n // 🧹 컴포넌트 언마운트시 정리\n return () =>\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]);\n });\n }, [handlers]);\n }\n\n // 타입 분석:\n // EventKey = 'open' | 'close' | 'closeAll'\n // Parameters<EventHandlers['open']> = [data: {component: Component, id:\n // string}]\n\n // const openEvent = createEvent('open');\n // openEvent의 타입: (data: {component: Component, id: string}) => void\n\n // openEvent({component: MyModal, id: '123'});\n // → dispatchEvent('overlay-kit:open', {component: MyModal, id: '123'})\n\n // payload[0]을 사용하는 이유:\n // 함수 호출: openEvent(arg1, arg2, arg3)\n // payload = [arg1, arg2, arg3]\n // payload[0] = arg1 (첫 번째 인자만 이벤트 데이터로 전달)\n\n function createEvent<EventKey extends keyof EventHandlers>(event: EventKey) {\n return (...payload: Parameters<EventHandlers[EventKey]>) =>\n dispatchEvent(`${prefix}:${String(event)}`, payload[0]);\n }\n\n return [useExternalEvents, createEvent] as const;\n}\n\n// 💡 이 패턴의 천재적인 점\n\n// 1. React 외부에서 React 내부 제어: overlay.open() 같은 명령형 API 가능\n// 2. 타입 안전성: TypeScript로 이벤트 타입 완벽 추론\n// 3. 메모리 안전: React Hook 생명주기와 완벽 동기화\n// 4. 플랫폼 호환: 웹/RN 모두 지원\n// 5. 네임스페이스: 이벤트 충돌 방지\n\nexport { createUseExternalEvents };\n","\n// 이벤트 이름\nexport type EventType = string | symbol;\n\n// 이벤트 핸들러\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;\n\n// 이벤트 핸들러 목록\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;\n\n// 이벤트 핸들러 맵\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | '*',\n EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\n// 이벤트 발행기\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n all: EventHandlerMap<Events>;\n\n on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n on(type: '*', handler: WildcardHandler<Events>): void;\n\n off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;\n off(type: '*', handler: WildcardHandler<Events>): void;\n\n emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;\n}\n\nexport function createEmitter<Events extends Record<EventType, unknown>>(\n all?: EventHandlerMap<Events>\n): Emitter<Events> {\n type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>;\n all = all || new Map();\n\n return {\n all,\n on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n handlers.push(handler);\n } else {\n all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n }\n },\n off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n all!.set(type, []);\n }\n }\n },\n emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n let handlers = all!.get(type);\n if (handlers) {\n (handlers as EventHandlerList<Events[keyof Events]>).slice().forEach((handler) => {\n handler(evt!);\n });\n }\n\n handlers = all!.get('*');\n if (handlers) {\n (handlers as WildCardEventHandlerList<Events>).slice().forEach((handler) => {\n handler(type, evt!);\n });\n }\n },\n };\n}","export function randomId() {\n return `overlay-kit-${Math.random().toString(36).slice(2, 11)}`;\n}","// 사용자가 실제로 사용하는 API 를 만드는 팩토리\n// overlay.open(), overlay.close 등\n\nimport React from \"react\";\nimport {\n OverlayAsyncControllerComponent,\n OverlayControllerComponent,\n} from \"./context/provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./context/provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./context/provider/modal-controller\";\nimport { createUseExternalEvents } from \"./utils/create-use-external-events\";\nimport { randomId } from \"./utils/random-id\";\n\nexport type OverlayEvent = {\n open: (args: {\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement;\n overlayId: string;\n componentKey: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n options?: any;\n }) => void;\n close: (overlayId: string) => void;\n unmount: (overlayId: string) => void;\n closeAll: () => void;\n unmountAll: () => void;\n};\n\ntype OpenOverlayOptions = {\n overlayId?: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n // BottomSheet options\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Modal options\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n enableDynamicSizing?: boolean;\n animationType?:\n | \"none\"\n | \"slide\"\n | \"fade\"\n | \"bounceIn\"\n | \"bounceInDown\"\n | \"bounceInUp\"\n | \"bounceInLeft\"\n | \"bounceInRight\"\n | \"bounceOut\"\n | \"bounceOutDown\"\n | \"bounceOutUp\"\n | \"bounceOutLeft\"\n | \"bounceOutRight\"\n | \"fadeIn\"\n | \"fadeInDown\"\n | \"fadeInDownBig\"\n | \"fadeInUp\"\n | \"fadeInUpBig\"\n | \"fadeInLeft\"\n | \"fadeInLeftBig\"\n | \"fadeInRight\"\n | \"fadeInRightBig\"\n | \"fadeOut\"\n | \"fadeOutDown\"\n | \"fadeOutDownBig\"\n | \"fadeOutUp\"\n | \"fadeOutUpBig\"\n | \"fadeOutLeft\"\n | \"fadeOutLeftBig\"\n | \"fadeOutRight\"\n | \"fadeOutRightBig\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n// id 받아\nexport function createOverlay(overlayId: string) {\n const [useOverlayEvent, createEvent] = createUseExternalEvents<OverlayEvent>(\n `${overlayId}/overlay-kit`\n );\n\n const open = (\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement,\n options?: OpenOverlayOptions\n ) => {\n const overlayId = options?.overlayId ?? randomId();\n const componentKey = randomId();\n const overlayType = options?.overlayType ?? \"overlay\";\n\n const dispatchOpenEvent = createEvent(\"open\");\n\n // 옵션에서 overlayType과 overlayId를 제외한 나머지를 options로 전달\n const { overlayId: _, overlayType: __, ...restOptions } = options || {};\n\n dispatchOpenEvent({\n controller,\n overlayId,\n componentKey,\n overlayType,\n options: restOptions,\n });\n return overlayId;\n };\n\n // openAsync는 모든 overlay 타입에서 사용 가능\n const openAsync = async <T>(\n controller:\n | OverlayAsyncControllerComponent<T>\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | ((props: any) => any),\n options?: OpenOverlayOptions\n ) => {\n return new Promise<T>((resolve) => {\n const wrappedController = (\n overlayProps: any,\n ...deprecatedLegacyContext: any[]\n ) => {\n const close = (param?: T) => {\n resolve(param as T);\n overlayProps.close();\n };\n const unmount = (param?: T) => {\n resolve(param as T);\n overlayProps.unmount();\n };\n const props = { ...overlayProps, close, unmount };\n return controller(props);\n };\n\n open(wrappedController, options);\n });\n };\n const close = createEvent(\"close\");\n const unmount = createEvent(\"unmount\");\n const closeAll = createEvent(\"closeAll\");\n const unmountAll = createEvent(\"unmountAll\");\n return {\n open,\n openAsync,\n close,\n unmount,\n closeAll,\n unmountAll,\n useOverlayEvent,\n };\n}\n","import { type Provider, createContext, useContext } from 'react';\n\ntype NullSymbolType = typeof NullSymbol;\nconst NullSymbol = Symbol('Null');\n\nexport type CreateContextReturn<T> = [Provider<T>, () => T];\n\nexport function createSafeContext<T>(displayName?: string): CreateContextReturn<T> {\n const Context = createContext<T | NullSymbolType>(NullSymbol);\n Context.displayName = displayName ?? 'SafeContext';\n\n function useSafeContext() {\n const context = useContext(Context);\n\n if (context === NullSymbol) {\n const error = new Error(`[${Context.displayName}]: Provider not found.`);\n error.name = '[Error] Context';\n\n throw error;\n }\n\n return context;\n }\n\n return [Context.Provider as any, useSafeContext];\n}\n","import { createSafeContext } from '../utils/create-safe-context';\nimport { type OverlayData } from './reducer';\n\n\nexport function createOverlaySafeContext() {\n const [OverlayContextProvider, useOverlayContext] = createSafeContext<OverlayData>('overlay-kit/OverlayContext');\n\n function useCurrentOverlay() {\n return useOverlayContext().current;\n }\n\n function useOverlayData() {\n return useOverlayContext().overlayData;\n }\n\n return { OverlayContextProvider, useCurrentOverlay, useOverlayData };\n}\n","import { OverlayControllerComponent } from \"./provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./provider/modal-controller\";\n\ntype OverlayId = string;\ntype OverlayItem = {\n /**\n * @description 오버레이 고유한 ID\n */\n id : OverlayId;\n /**\n * @description 오버레이 컴포넌트의 고유한 키\n * 컴포넌트가 언마운트시 사용됩니다.\n */\n componentKey: string;\n isOpen: boolean;\n isMounted: boolean;\n controller: OverlayControllerComponent | BottomSheetControllerComponent | ModalControllerComponent;\n overlayType?: 'overlay' | 'bottomSheet' | 'modal';\n options?: any;\n}\nexport type OverlayData = {\n current: OverlayId | null; // 현재 열려있는 오버레이 ID\n overlayOrderList: OverlayId[];\n overlayData: Record<OverlayId, OverlayItem>;\n}\nexport type OverlayReducerAction =\n | { type: 'ADD'; overlay: OverlayItem }\n | { type: 'OPEN'; overlayId: string }\n | { type: 'CLOSE'; overlayId: string }\n | { type: 'REMOVE'; overlayId: string }\n | { type: 'CLOSE_ALL' }\n | { type: 'REMOVE_ALL' };\n\n/**\n * 오버레이를 닫거나 제거할 때, 어떤 오버레이를 현재(current)로 지정할지 결정합니다.\n *\n * @description 마지막 오버레이를 닫을 경우, 그 이전 오버레이를 현재로 지정합니다.\n * @description 중간에 있는 오버레이를 닫을 경우, 마지막 오버레이를 현재로 지정합니다.\n *\n * @example open - [1, 2, 3, 4]\n * close 2 => current: 4\n * close 4 => current: 3\n * close 3 => current: 1\n * close 1 => current: null\n *\n * @param overlayOrderList 오버레이 ID가 순서대로 담긴 리스트\n * @param overlayData 오버레이 데이터 맵\n * @param targetOverlayId 닫거나 제거하려는 오버레이의 ID\n * @returns 현재로 지정될 오버레이의 ID, 없으면 null\n */\nexport const determineCurrentOverlayId = (overlayOrderList: OverlayId[], overlayData: Record<OverlayId, OverlayItem>, targetOverlayId: OverlayId): OverlayId | null => {\n // 1단계: 열린 오버레이들만 필터링\n\n const openedOverlayOrderList = overlayOrderList.filter(\n (orderedOverlayId) => overlayData[orderedOverlayId].isOpen === true\n );\n // 2단계: 닫힐 오버레이의 위치 찾기\n const targetIndexInOpenedList = openedOverlayOrderList.findIndex((item) => item === targetOverlayId);\n\n // 3단계: 다음 활성 오버레이 결정\n return targetIndexInOpenedList === openedOverlayOrderList.length - 1\n ? openedOverlayOrderList[targetIndexInOpenedList - 1] ?? null // 마지막이면 이전 것\n : openedOverlayOrderList[openedOverlayOrderList.length - 1] ?? null;// 중간이면 최상위\n\n}\n\n/** 동작 예시:\n * \n *\n * // 상황: 오버레이 [1, 2, 3, 4]가 순서대로 열려있음\n * overlayOrderList = [\"modal-1\", \"modal-2\", \"modal-3\", \"modal-4\"];\n * // 모두 isOpen: true\n *\n * // 케이스 1: 최상위(4번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-4\");\n * // → \"modal-3\" (바로 아래가 활성화)\n *\n * // 케이스 2: 중간(2번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-2\");\n * // → \"modal-4\" (최상위가 여전히 활성)\n *\n * // 케이스 3: 마지막 남은 것 닫기\n * determineCurrentOverlayId([\"modal-1\"], data, \"modal-1\");\n * // → null (더 이상 활성 오버레이 없음)\n */\n\n// 상태 변경 로직\nexport function overlayReducer(state: OverlayData, action: OverlayReducerAction): OverlayData {\n switch (action.type) {\n case 'ADD': {\n if (state.overlayData[action.overlay.id] != null && state.overlayData[action.overlay.id].isOpen === false) {\n const overlay = state.overlayData[action.overlay.id];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n current: action.overlay.id,\n overlayData: {\n ...state.overlayData,\n [action.overlay.id]: { ...overlay, isOpen: true },\n },\n };\n }\n\n const isExisted = state.overlayOrderList.includes(action.overlay.id);\n\n if (isExisted && state.overlayData[action.overlay.id].isOpen === true) {\n throw new Error(\n `You can't open the multiple overlays with the same overlayId(${action.overlay.id}). Please set a different id.`\n );\n }\n\n return {\n current: action.overlay.id,\n /**\n * @description Brings the overlay to the front when reopened after closing without unmounting.\n */\n overlayOrderList: [...state.overlayOrderList.filter((item) => item !== action.overlay.id), action.overlay.id],\n overlayData: isExisted\n ? state.overlayData\n : {\n ...state.overlayData,\n [action.overlay.id]: action.overlay,\n },\n };\n }\n case 'OPEN': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: { ...overlay, isOpen: true, isMounted: true },\n },\n };\n }\n case 'CLOSE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already closed\n if (overlay == null || !overlay.isOpen) {\n return state;\n }\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n ...state,\n current: currentOverlayId,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: {\n ...state.overlayData[action.overlayId],\n isOpen: false,\n },\n },\n };\n }\n case 'REMOVE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist\n if (overlay == null) {\n return state;\n }\n\n const remainingOverlays = state.overlayOrderList.filter((item) => item !== action.overlayId);\n if (state.overlayOrderList.length === remainingOverlays.length) {\n return state;\n }\n\n const copiedOverlayData = { ...state.overlayData };\n delete copiedOverlayData[action.overlayId];\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n current: currentOverlayId,\n overlayOrderList: remainingOverlays,\n overlayData: copiedOverlayData,\n };\n }\n case 'CLOSE_ALL': {\n // ignore if there is no overlay\n if (Object.keys(state.overlayData).length === 0) {\n return state;\n }\n\n return {\n ...state,\n current: null,\n overlayData: Object.keys(state.overlayData).reduce(\n (prev, curr) => ({\n ...prev,\n [curr]: {\n ...state.overlayData[curr],\n isOpen: false,\n } satisfies OverlayItem,\n }),\n {} satisfies Record<string, OverlayItem>\n ),\n };\n }\n case 'REMOVE_ALL': {\n return { current: null, overlayOrderList: [], overlayData: {} };\n }\n }\n}","import { createOverlayProvider } from '../context/provider';\n\nexport const { overlay, OverlayProvider, useCurrentOverlay, useOverlayData } = createOverlayProvider();\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function experimental_createOverlayContext() {\n return createOverlayProvider();\n}"],"mappings":"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","names":["useCallback","useEffect","memo","useEffect","jsx","memo","useEffect","_a","React","memo","useEffect","useState","View","StyleSheet","jsx","memo","useState","useEffect","styles","StyleSheet","View","React","useEffect","useEffect","overlayId","close","unmount","useCurrentOverlay","useOverlayData","overlay","BottomSheetModalProvider","jsx","overlay","useCurrentOverlay","useOverlayData","OverlayProvider","useCallback","overlayId","useEffect","BottomSheetModalProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/context/provider/index.tsx","../src/context/provider/content-overlay-controller.tsx","../src/context/provider/bottom-sheet-controller.tsx","../src/context/provider/modal-controller.tsx","../src/event.ts","../src/utils/create-use-external-events.ts","../src/utils/emitter.ts","../src/utils/random-id.ts","../src/utils/create-safe-context.ts","../src/context/context.ts","../src/context/reducer.ts","../src/utils/create-overlay-context.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useReducer,\n type PropsWithChildren,\n} from \"react\";\nimport { View } from \"react-native\";\nimport { ContentOverlayController } from \"./content-overlay-controller\";\nimport { ContentBottomSheetController } from \"./bottom-sheet-controller\";\nimport { ContentModalController } from \"./modal-controller\";\nimport { type OverlayEvent, createOverlay } from \"../../event\";\nimport { randomId } from \"../../utils/random-id\";\nimport { createOverlaySafeContext } from \"../context\";\nimport { overlayReducer } from \"../reducer\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport { BottomSheetModalProvider } from \"@gorhom/bottom-sheet\";\n\nexport function createOverlayProvider() {\n const overlayId = randomId();\n const { useOverlayEvent, ...overlay } = createOverlay(overlayId);\n\n const { OverlayContextProvider, useCurrentOverlay, useOverlayData } =\n createOverlaySafeContext();\n\n function OverlayProvider({ children }: PropsWithChildren) {\n const [overlayState, overlayDispatch] = useReducer(overlayReducer, {\n current: null,\n overlayOrderList: [],\n overlayData: {},\n });\n\n // Overlay 이벤트 핸들러들\n const overlayOpen: OverlayEvent[\"open\"] = useCallback(\n ({\n controller,\n overlayId,\n componentKey,\n overlayType = \"overlay\",\n options,\n }) => {\n overlayDispatch({\n type: \"ADD\",\n overlay: {\n id: overlayId,\n componentKey,\n isOpen: true,\n isMounted: true,\n controller: controller,\n overlayType,\n options,\n },\n });\n },\n []\n );\n\n const close = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, []);\n\n const unmount = useCallback((overlayId: string) => {\n overlayDispatch({ type: \"REMOVE\", overlayId });\n }, []);\n\n const closeAll = useCallback(() => {\n overlayDispatch({ type: \"CLOSE_ALL\" });\n }, []);\n\n const unmountAll = useCallback(() => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n }, []);\n\n // 이벤트 리스너 등록\n useOverlayEvent({\n open: overlayOpen,\n close,\n unmount,\n closeAll,\n unmountAll,\n });\n\n useEffect(() => {\n return () => {\n overlayDispatch({ type: \"REMOVE_ALL\" });\n };\n }, []);\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <BottomSheetModalProvider>\n <OverlayContextProvider value={overlayState}>\n {children}\n\n {overlayState.overlayOrderList.map((item) => {\n const overlayItem = overlayState.overlayData[item];\n const {\n id: currentOverlayId,\n componentKey,\n isOpen,\n controller: Controller,\n overlayType,\n options,\n } = overlayItem;\n\n // 타입에 따라 다른 컨트롤러 렌더링\n if (overlayType === \"bottomSheet\") {\n return (\n <ContentBottomSheetController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else if (overlayType === \"modal\") {\n // 모달의 경우 현재 활성화된 모달만 표시\n const isCurrentModal =\n overlayState.current === currentOverlayId;\n const shouldShow = isOpen && isCurrentModal;\n\n return (\n <ContentModalController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n options={options}\n />\n );\n } else {\n // 기존 overlay (backward compatibility)\n return (\n <ContentOverlayController\n key={componentKey}\n isOpen={isOpen}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n />\n );\n }\n })}\n </OverlayContextProvider>\n </BottomSheetModalProvider>\n </GestureHandlerRootView>\n );\n }\n\n return {\n overlay,\n OverlayProvider,\n useCurrentOverlay,\n useOverlayData,\n };\n}\n","import React, { type FC, memo, useEffect, type Dispatch } from \"react\";\nimport { Modal } from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype OverlayControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n};\n\ntype OverlayAsyncControllerProps<T> = Omit<OverlayControllerProps, \"close\"> & {\n close: (param: T) => void;\n};\n\nexport type OverlayControllerComponent = FC<OverlayControllerProps>;\nexport type OverlayAsyncControllerComponent<T> = FC<\n OverlayAsyncControllerProps<T>\n>;\n\ntype ContentOverlayControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: OverlayControllerComponent;\n};\n\nexport const ContentOverlayController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n }: ContentOverlayControllerProps) => {\n useEffect(() => {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n }, [overlayDispatch, overlayId]);\n\n return (\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n />\n );\n }\n);\n","import React, {\n type FC,\n memo,\n useEffect,\n useRef,\n type Dispatch,\n useCallback,\n useState,\n} from \"react\";\nimport BottomSheet, {\n BottomSheetModal,\n BottomSheetView,\n BottomSheetFlatList,\n BottomSheetScrollView,\n BottomSheetBackdrop,\n BottomSheetModalProvider,\n BottomSheetTextInput,\n} from \"@gorhom/bottom-sheet\";\nimport {\n StyleProp,\n ViewStyle,\n ListRenderItem,\n View,\n StyleSheet,\n Platform,\n Keyboard,\n} from \"react-native\";\nimport { useReducedMotion } from \"react-native-reanimated\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype BottomSheetControllerProps<T = any> = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Enhanced features\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n // FlatList support\n isFlatList?: boolean;\n data?: ArrayLike<T> | null | undefined;\n renderItem?: ListRenderItem<T> | null | undefined;\n keyExtractor?: ((item: T, index: number) => string) | undefined;\n contentContainerStyle?: StyleProp<ViewStyle> | undefined;\n ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;\n flatListHeader?: React.ReactNode;\n flatListFooter?: React.ReactNode;\n // Backdrop\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n onBackdropPress?: () => void;\n // Dynamic sizing\n enableDynamicSizing?: boolean;\n // Scrolling\n enableScrolling?: boolean;\n // Styling\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n // Loading & empty state\n isLoading?: boolean;\n emptyText?: string;\n extraData?: any;\n // Keyboard height (Android)\n keyboardHeight?: number;\n};\n\nexport type BottomSheetControllerComponent<T = any> = FC<\n BottomSheetControllerProps<T>\n>;\n\ntype ContentBottomSheetControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: Dispatch<OverlayReducerAction>;\n controller: BottomSheetControllerComponent;\n options?: {\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n enableBackdrop?: boolean;\n backdropOpacity?: number;\n enableDynamicSizing?: boolean;\n backgroundStyle?: StyleProp<ViewStyle>;\n handleStyle?: StyleProp<ViewStyle>;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n [key: string]: any;\n };\n};\n\nexport const ContentBottomSheetController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentBottomSheetControllerProps) => {\n const bottomSheetRef = useRef<BottomSheet>(null);\n const reducedMotion = useReducedMotion();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n // --- Android keyboard handling defaults ---\n // On Android, the sheet won't move with the keyboard unless:\n // 1) Activity windowSoftInputMode = \"adjustResize\"\n // 2) bottom-sheet uses keyboardBehavior=\"extend\"\n // 3) Text inputs inside sheet use BottomSheetTextInput\n\n const {\n snapPoints,\n enablePanDownToClose = true,\n enableBackdrop = true,\n backdropOpacity = 0.5,\n enableDynamicSizing = true,\n backgroundStyle = {},\n handleStyle = {},\n keyboardBehavior = Platform.OS === \"android\" ? \"extend\" : \"interactive\",\n keyboardBlurBehavior = \"restore\",\n androidKeyboardInputMode = \"adjustResize\",\n ...restOptions\n } = options;\n\n // Android 키보드 높이 감지\n useEffect(() => {\n if (Platform.OS === \"android\") {\n const keyboardDidShowListener = Keyboard.addListener(\n \"keyboardDidShow\",\n (e) => setKeyboardHeight(e.endCoordinates.height)\n );\n const keyboardDidHideListener = Keyboard.addListener(\n \"keyboardDidHide\",\n () => setKeyboardHeight(0)\n );\n\n return () => {\n keyboardDidShowListener.remove();\n keyboardDidHideListener.remove();\n };\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n const rafId = requestAnimationFrame(() => {\n bottomSheetRef.current?.expand();\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n return () => cancelAnimationFrame(rafId);\n } else {\n bottomSheetRef.current?.close();\n }\n }, [isOpen, overlayDispatch, overlayId]);\n\n const handleClose = useCallback(() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }, [overlayDispatch, overlayId]);\n\n // 백드롭 렌더링\n const renderBackdrop = useCallback(\n (props: any) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={1}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior=\"close\"\n onPress={() => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n }}\n />\n ),\n [backdropOpacity, keyboardHeight]\n );\n // callbacks\n const handleSheetChange = useCallback((index: number) => {\n console.log(\"handleSheetChange\", index);\n }, []);\n\n if (!isOpen) return null;\n\n return (\n <BottomSheet\n ref={bottomSheetRef}\n onChange={handleSheetChange}\n android_keyboardInputMode={androidKeyboardInputMode}\n keyboardBehavior={keyboardBehavior}\n snapPoints={enableDynamicSizing ? undefined : snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n onClose={handleClose}\n keyboardBlurBehavior={keyboardBlurBehavior}\n index={0}\n backdropComponent={enableBackdrop ? renderBackdrop : undefined}\n backgroundStyle={[\n {\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n backgroundStyle,\n ]}\n handleStyle={[\n {\n backgroundColor: \"transparent\",\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n },\n handleStyle,\n ]}\n enableDynamicSizing={enableDynamicSizing}\n animateOnMount={!reducedMotion}\n >\n <Controller\n isOpen={isOpen}\n overlayId={overlayId}\n snapPoints={snapPoints}\n enablePanDownToClose={enablePanDownToClose}\n close={() => overlayDispatch({ type: \"CLOSE\", overlayId })}\n unmount={() => overlayDispatch({ type: \"REMOVE\", overlayId })}\n keyboardHeight={keyboardHeight}\n {...restOptions}\n />\n </BottomSheet>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n contentContainer: {\n flex: 1,\n },\n});\n","import React, { type FC, memo, useEffect, useState } from \"react\";\nimport {\n Modal,\n View,\n TouchableWithoutFeedback,\n Animated,\n StyleSheet,\n Dimensions,\n Pressable,\n} from \"react-native\";\nimport { type OverlayReducerAction } from \"../reducer\";\n\ntype ModalControllerProps = {\n overlayId: string;\n isOpen: boolean;\n close: () => void;\n unmount: () => void;\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n\nexport type ModalControllerComponent<T = {}> = FC<ModalControllerProps & T>;\n\ntype ContentModalControllerProps = {\n isOpen: boolean;\n overlayId: string;\n overlayDispatch: React.Dispatch<OverlayReducerAction>;\n controller: ModalControllerComponent | React.ReactElement;\n options?: {\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n animationType?: \"none\" | \"slide\" | \"fade\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n };\n};\n\nconst { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get(\"window\");\n\nexport const ContentModalController = memo(\n ({\n isOpen,\n overlayId,\n overlayDispatch,\n controller: Controller,\n options = {},\n }: ContentModalControllerProps) => {\n const {\n modalType = \"center\",\n backdropOpacity = 0.5,\n animationType = \"fade\",\n swipeDirection,\n } = options;\n\n const [backdropAnimation] = useState(new Animated.Value(0));\n const [contentAnimation] = useState(new Animated.Value(0));\n\n useEffect(() => {\n if (isOpen) {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\n });\n\n // 애니메이션 시작\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 1,\n duration: 300,\n useNativeDriver: true,\n }),\n ]).start();\n } else {\n // 닫기 애니메이션\n Animated.parallel([\n Animated.timing(backdropAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.timing(contentAnimation, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start();\n }\n }, [\n isOpen,\n overlayDispatch,\n overlayId,\n backdropAnimation,\n contentAnimation,\n ]);\n\n const handleClose = () => {\n overlayDispatch({ type: \"CLOSE\", overlayId });\n };\n\n const getContainerStyle = () => {\n switch (modalType) {\n case \"bottom\":\n return styles.bottomContainer;\n case \"top\":\n return styles.topContainer;\n case \"left\":\n return styles.leftContainer;\n case \"right\":\n return styles.rightContainer;\n default: // center\n return styles.centerContainer;\n }\n };\n\n const getContentAnimationStyle = () => {\n const baseOpacity = {\n opacity: contentAnimation,\n };\n\n switch (modalType) {\n case \"bottom\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"top\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateY: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_HEIGHT, 0],\n }),\n },\n ],\n };\n case \"left\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [-SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n case \"right\":\n return {\n ...baseOpacity,\n transform: [\n {\n translateX: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [SCREEN_WIDTH, 0],\n }),\n },\n ],\n };\n default: // center\n if (animationType === \"slide\") {\n return {\n ...baseOpacity,\n transform: [\n {\n scale: contentAnimation.interpolate({\n inputRange: [0, 1],\n outputRange: [0.8, 1],\n }),\n },\n ],\n };\n }\n return baseOpacity;\n }\n };\n\n // Modal 대신 절대 위치 View 사용 (필요시)\n if (!isOpen) return null;\n\n return (\n <Modal\n visible={isOpen}\n transparent={true}\n animationType=\"none\"\n onRequestClose={handleClose}\n statusBarTranslucent={true}\n presentationStyle=\"overFullScreen\"\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={handleClose}>\n <Animated.View\n style={[\n styles.backdrop,\n {\n backgroundColor: `rgba(0, 0, 0, ${backdropOpacity})`,\n opacity: backdropAnimation,\n },\n ]}\n >\n <View style={StyleSheet.absoluteFill} pointerEvents=\"box-none\">\n <Animated.View\n style={[getContainerStyle(), getContentAnimationStyle()]}\n pointerEvents=\"box-none\"\n >\n <Pressable onPress={() => {}}>\n {React.isValidElement(Controller)\n ? React.cloneElement(\n Controller as React.ReactElement<any>,\n {\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n }\n )\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n modalType,\n backdropOpacity,\n animationType,\n swipeDirection,\n close: () =>\n overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () =>\n overlayDispatch({ type: \"REMOVE\", overlayId }),\n })}\n </Pressable>\n </Animated.View>\n </View>\n </Animated.View>\n </Pressable>\n </Modal>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n backdrop: {\n ...StyleSheet.absoluteFillObject,\n },\n centerContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n },\n bottomContainer: {\n flex: 1,\n justifyContent: \"flex-end\",\n },\n topContainer: {\n flex: 1,\n justifyContent: \"flex-start\",\n },\n leftContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n },\n rightContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"flex-end\",\n },\n});\n","// 사용자가 실제로 사용하는 API 를 만드는 팩토리\n// overlay.open(), overlay.close 등\n\nimport React from \"react\";\nimport {\n OverlayAsyncControllerComponent,\n OverlayControllerComponent,\n} from \"./context/provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./context/provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./context/provider/modal-controller\";\nimport { createUseExternalEvents } from \"./utils/create-use-external-events\";\nimport { randomId } from \"./utils/random-id\";\n\nexport type OverlayEvent = {\n open: (args: {\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement;\n overlayId: string;\n componentKey: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n options?: any;\n }) => void;\n close: (overlayId: string) => void;\n unmount: (overlayId: string) => void;\n closeAll: () => void;\n unmountAll: () => void;\n};\n\ntype OpenOverlayOptions = {\n overlayId?: string;\n overlayType?: \"overlay\" | \"bottomSheet\" | \"modal\";\n // BottomSheet options\n snapPoints?: (string | number)[];\n enablePanDownToClose?: boolean;\n // Modal options\n modalType?: \"center\" | \"bottom\" | \"top\" | \"left\" | \"right\";\n backdropOpacity?: number;\n keyboardBehavior?: \"interactive\" | \"extend\" | \"fillParent\";\n keyboardBlurBehavior?: \"restore\" | \"none\";\n androidKeyboardInputMode?: \"adjustResize\" | \"adjustPan\";\n enableDynamicSizing?: boolean;\n animationType?:\n | \"none\"\n | \"slide\"\n | \"fade\"\n | \"bounceIn\"\n | \"bounceInDown\"\n | \"bounceInUp\"\n | \"bounceInLeft\"\n | \"bounceInRight\"\n | \"bounceOut\"\n | \"bounceOutDown\"\n | \"bounceOutUp\"\n | \"bounceOutLeft\"\n | \"bounceOutRight\"\n | \"fadeIn\"\n | \"fadeInDown\"\n | \"fadeInDownBig\"\n | \"fadeInUp\"\n | \"fadeInUpBig\"\n | \"fadeInLeft\"\n | \"fadeInLeftBig\"\n | \"fadeInRight\"\n | \"fadeInRightBig\"\n | \"fadeOut\"\n | \"fadeOutDown\"\n | \"fadeOutDownBig\"\n | \"fadeOutUp\"\n | \"fadeOutUpBig\"\n | \"fadeOutLeft\"\n | \"fadeOutLeftBig\"\n | \"fadeOutRight\"\n | \"fadeOutRightBig\";\n swipeDirection?:\n | \"up\"\n | \"down\"\n | \"left\"\n | \"right\"\n | Array<\"up\" | \"down\" | \"left\" | \"right\">;\n};\n// id 받아\nexport function createOverlay(overlayId: string) {\n const [useOverlayEvent, createEvent] = createUseExternalEvents<OverlayEvent>(\n `${overlayId}/overlay-kit`\n );\n\n const open = (\n controller:\n | OverlayControllerComponent\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | React.ReactElement,\n options?: OpenOverlayOptions\n ) => {\n const overlayId = options?.overlayId ?? randomId();\n const componentKey = randomId();\n const overlayType = options?.overlayType ?? \"overlay\";\n\n const dispatchOpenEvent = createEvent(\"open\");\n\n // 옵션에서 overlayType과 overlayId를 제외한 나머지를 options로 전달\n const { overlayId: _, overlayType: __, ...restOptions } = options || {};\n\n // JSX 엘리먼트인 경우 wrapper 컴포넌트로 감싸기\n let finalController;\n if (React.isValidElement(controller)) {\n finalController = (props: any) => {\n return React.cloneElement(controller as React.ReactElement, {\n ...(controller.props || {}),\n ...props,\n close: props.close,\n unmount: props.unmount,\n });\n };\n } else {\n finalController = controller;\n }\n\n dispatchOpenEvent({\n controller: finalController,\n overlayId,\n componentKey,\n overlayType,\n options: restOptions,\n });\n return overlayId;\n };\n\n // openAsync는 모든 overlay 타입에서 사용 가능\n const openAsync = async <T>(\n controller:\n | OverlayAsyncControllerComponent<T>\n | BottomSheetControllerComponent\n | ModalControllerComponent\n | ((props: any) => any),\n options?: OpenOverlayOptions\n ) => {\n return new Promise<T>((resolve) => {\n const wrappedController = (overlayProps: any) => {\n const close = (param?: T) => {\n resolve(param as T);\n overlayProps.close();\n };\n const unmount = (param?: T) => {\n resolve(param as T);\n overlayProps.unmount();\n };\n const props = { ...overlayProps, close, unmount };\n return controller(props);\n };\n\n open(wrappedController, options);\n });\n };\n const close = createEvent(\"close\");\n const unmount = createEvent(\"unmount\");\n const closeAll = createEvent(\"closeAll\");\n const unmountAll = createEvent(\"unmountAll\");\n return {\n open,\n openAsync,\n close,\n unmount,\n closeAll,\n unmountAll,\n useOverlayEvent,\n };\n}\n","import { useEffect } from \"react\";\nimport { createEmitter } from \"./emitter\";\n\nconst emitter = createEmitter();\n\n// React Native에서는 useEffect를 사용 (useLayoutEffect 대신)\nfunction useClientEffect(...args: Parameters<typeof useEffect>) {\n // RN에서는 항상 useEffect 실행\n useEffect(...args);\n}\n\n// 단순한 wrapper 함수\n// emitter.emit을 한번 감싼 이유는 나중에 로깅, 디버깅 등 추가 기능을 넣기 위함\nfunction dispatchEvent<Detail>(type: string, detail?: Detail) {\n emitter.emit(type, detail);\n}\n\n// 메인 팩토리 함수\n// 사용 예\n// createUseExternalEvents<OverlayEvents>('overlay-kit')\n// prefix의 역할:\n// - 'overlay-kit' → 실제 이벤트명은 overlay-kit:open, overlay-kit:close\n// - 네임스페이스로 이벤트 충돌 방지\n\nfunction createUseExternalEvents<\n EventHandlers extends Record<string, (params: any) => void>\n>(prefix: string) {\n function useExternalEvents(events: EventHandlers) {\n // 변환 과정:\n // 입력:\n // events = {\n // open: (data) => console.log('열기', data),\n // close: (id) => console.log('닫기', id)\n // }\n\n // 변환 결과:\n // handlers = {\n // 'overlay-kit:open': (event) => events.open(event),\n // 'overlay-kit:close': (event) => events.close(event)\n // }\n\n const handlers = Object.keys(events).reduce<Record<string, () => void>>(\n (prev, eventKey) => {\n const currentEventKeys = `${prefix}:${eventKey}`;\n\n return {\n ...prev,\n [currentEventKeys]: function (event: unknown) {\n events[eventKey](event);\n } as () => void,\n };\n },\n {}\n );\n\n useClientEffect(() => {\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]); // 🔥 기존 핸들러 제거\n // (중복 방지)\n emitter.on(eventKey, handlers[eventKey]); // 🔥 새로운 핸들러 등록\n });\n\n // 🧹 컴포넌트 언마운트시 정리\n return () =>\n Object.keys(handlers).forEach((eventKey) => {\n emitter.off(eventKey, handlers[eventKey]);\n });\n }, [handlers]);\n }\n\n // 타입 분석:\n // EventKey = 'open' | 'close' | 'closeAll'\n // Parameters<EventHandlers['open']> = [data: {component: Component, id:\n // string}]\n\n // const openEvent = createEvent('open');\n // openEvent의 타입: (data: {component: Component, id: string}) => void\n\n // openEvent({component: MyModal, id: '123'});\n // → dispatchEvent('overlay-kit:open', {component: MyModal, id: '123'})\n\n // payload[0]을 사용하는 이유:\n // 함수 호출: openEvent(arg1, arg2, arg3)\n // payload = [arg1, arg2, arg3]\n // payload[0] = arg1 (첫 번째 인자만 이벤트 데이터로 전달)\n\n function createEvent<EventKey extends keyof EventHandlers>(event: EventKey) {\n return (...payload: Parameters<EventHandlers[EventKey]>) =>\n dispatchEvent(`${prefix}:${String(event)}`, payload[0]);\n }\n\n return [useExternalEvents, createEvent] as const;\n}\n\n// 💡 이 패턴의 천재적인 점\n\n// 1. React 외부에서 React 내부 제어: overlay.open() 같은 명령형 API 가능\n// 2. 타입 안전성: TypeScript로 이벤트 타입 완벽 추론\n// 3. 메모리 안전: React Hook 생명주기와 완벽 동기화\n// 4. 플랫폼 호환: 웹/RN 모두 지원\n// 5. 네임스페이스: 이벤트 충돌 방지\n\nexport { createUseExternalEvents };\n","\n// 이벤트 이름\nexport type EventType = string | symbol;\n\n// 이벤트 핸들러\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;\n\n// 이벤트 핸들러 목록\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;\n\n// 이벤트 핸들러 맵\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n keyof Events | '*',\n EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\n// 이벤트 발행기\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n all: EventHandlerMap<Events>;\n\n on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n on(type: '*', handler: WildcardHandler<Events>): void;\n\n off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;\n off(type: '*', handler: WildcardHandler<Events>): void;\n\n emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;\n}\n\nexport function createEmitter<Events extends Record<EventType, unknown>>(\n all?: EventHandlerMap<Events>\n): Emitter<Events> {\n type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>;\n all = all || new Map();\n\n return {\n all,\n on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n handlers.push(handler);\n } else {\n all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n }\n },\n off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n all!.set(type, []);\n }\n }\n },\n emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n let handlers = all!.get(type);\n if (handlers) {\n (handlers as EventHandlerList<Events[keyof Events]>).slice().forEach((handler) => {\n handler(evt!);\n });\n }\n\n handlers = all!.get('*');\n if (handlers) {\n (handlers as WildCardEventHandlerList<Events>).slice().forEach((handler) => {\n handler(type, evt!);\n });\n }\n },\n };\n}","export function randomId() {\n return `overlay-kit-${Math.random().toString(36).slice(2, 11)}`;\n}","import { type Provider, createContext, useContext } from 'react';\n\ntype NullSymbolType = typeof NullSymbol;\nconst NullSymbol = Symbol('Null');\n\nexport type CreateContextReturn<T> = [Provider<T>, () => T];\n\nexport function createSafeContext<T>(displayName?: string): CreateContextReturn<T> {\n const Context = createContext<T | NullSymbolType>(NullSymbol);\n Context.displayName = displayName ?? 'SafeContext';\n\n function useSafeContext() {\n const context = useContext(Context);\n\n if (context === NullSymbol) {\n const error = new Error(`[${Context.displayName}]: Provider not found.`);\n error.name = '[Error] Context';\n\n throw error;\n }\n\n return context;\n }\n\n return [Context.Provider as any, useSafeContext];\n}\n","import { createSafeContext } from '../utils/create-safe-context';\nimport { type OverlayData } from './reducer';\n\n\nexport function createOverlaySafeContext() {\n const [OverlayContextProvider, useOverlayContext] = createSafeContext<OverlayData>('overlay-kit/OverlayContext');\n\n function useCurrentOverlay() {\n return useOverlayContext().current;\n }\n\n function useOverlayData() {\n return useOverlayContext().overlayData;\n }\n\n return { OverlayContextProvider, useCurrentOverlay, useOverlayData };\n}\n","import { OverlayControllerComponent } from \"./provider/content-overlay-controller\";\nimport { BottomSheetControllerComponent } from \"./provider/bottom-sheet-controller\";\nimport { ModalControllerComponent } from \"./provider/modal-controller\";\n\ntype OverlayId = string;\ntype OverlayItem = {\n /**\n * @description 오버레이 고유한 ID\n */\n id : OverlayId;\n /**\n * @description 오버레이 컴포넌트의 고유한 키\n * 컴포넌트가 언마운트시 사용됩니다.\n */\n componentKey: string;\n isOpen: boolean;\n isMounted: boolean;\n controller: OverlayControllerComponent | BottomSheetControllerComponent | ModalControllerComponent;\n overlayType?: 'overlay' | 'bottomSheet' | 'modal';\n options?: any;\n}\nexport type OverlayData = {\n current: OverlayId | null; // 현재 열려있는 오버레이 ID\n overlayOrderList: OverlayId[];\n overlayData: Record<OverlayId, OverlayItem>;\n}\nexport type OverlayReducerAction =\n | { type: 'ADD'; overlay: OverlayItem }\n | { type: 'OPEN'; overlayId: string }\n | { type: 'CLOSE'; overlayId: string }\n | { type: 'REMOVE'; overlayId: string }\n | { type: 'CLOSE_ALL' }\n | { type: 'REMOVE_ALL' };\n\n/**\n * 오버레이를 닫거나 제거할 때, 어떤 오버레이를 현재(current)로 지정할지 결정합니다.\n *\n * @description 마지막 오버레이를 닫을 경우, 그 이전 오버레이를 현재로 지정합니다.\n * @description 중간에 있는 오버레이를 닫을 경우, 마지막 오버레이를 현재로 지정합니다.\n *\n * @example open - [1, 2, 3, 4]\n * close 2 => current: 4\n * close 4 => current: 3\n * close 3 => current: 1\n * close 1 => current: null\n *\n * @param overlayOrderList 오버레이 ID가 순서대로 담긴 리스트\n * @param overlayData 오버레이 데이터 맵\n * @param targetOverlayId 닫거나 제거하려는 오버레이의 ID\n * @returns 현재로 지정될 오버레이의 ID, 없으면 null\n */\nexport const determineCurrentOverlayId = (overlayOrderList: OverlayId[], overlayData: Record<OverlayId, OverlayItem>, targetOverlayId: OverlayId): OverlayId | null => {\n // 1단계: 열린 오버레이들만 필터링\n\n const openedOverlayOrderList = overlayOrderList.filter(\n (orderedOverlayId) => overlayData[orderedOverlayId].isOpen === true\n );\n // 2단계: 닫힐 오버레이의 위치 찾기\n const targetIndexInOpenedList = openedOverlayOrderList.findIndex((item) => item === targetOverlayId);\n\n // 3단계: 다음 활성 오버레이 결정\n return targetIndexInOpenedList === openedOverlayOrderList.length - 1\n ? openedOverlayOrderList[targetIndexInOpenedList - 1] ?? null // 마지막이면 이전 것\n : openedOverlayOrderList[openedOverlayOrderList.length - 1] ?? null;// 중간이면 최상위\n\n}\n\n/** 동작 예시:\n * \n *\n * // 상황: 오버레이 [1, 2, 3, 4]가 순서대로 열려있음\n * overlayOrderList = [\"modal-1\", \"modal-2\", \"modal-3\", \"modal-4\"];\n * // 모두 isOpen: true\n *\n * // 케이스 1: 최상위(4번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-4\");\n * // → \"modal-3\" (바로 아래가 활성화)\n *\n * // 케이스 2: 중간(2번) 닫기\n * determineCurrentOverlayId(list, data, \"modal-2\");\n * // → \"modal-4\" (최상위가 여전히 활성)\n *\n * // 케이스 3: 마지막 남은 것 닫기\n * determineCurrentOverlayId([\"modal-1\"], data, \"modal-1\");\n * // → null (더 이상 활성 오버레이 없음)\n */\n\n// 상태 변경 로직\nexport function overlayReducer(state: OverlayData, action: OverlayReducerAction): OverlayData {\n switch (action.type) {\n case 'ADD': {\n if (state.overlayData[action.overlay.id] != null && state.overlayData[action.overlay.id].isOpen === false) {\n const overlay = state.overlayData[action.overlay.id];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n current: action.overlay.id,\n overlayData: {\n ...state.overlayData,\n [action.overlay.id]: { ...overlay, isOpen: true },\n },\n };\n }\n\n const isExisted = state.overlayOrderList.includes(action.overlay.id);\n\n if (isExisted && state.overlayData[action.overlay.id].isOpen === true) {\n throw new Error(\n `You can't open the multiple overlays with the same overlayId(${action.overlay.id}). Please set a different id.`\n );\n }\n\n return {\n current: action.overlay.id,\n /**\n * @description Brings the overlay to the front when reopened after closing without unmounting.\n */\n overlayOrderList: [...state.overlayOrderList.filter((item) => item !== action.overlay.id), action.overlay.id],\n overlayData: isExisted\n ? state.overlayData\n : {\n ...state.overlayData,\n [action.overlay.id]: action.overlay,\n },\n };\n }\n case 'OPEN': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already open\n if (overlay == null || overlay.isOpen) {\n return state;\n }\n\n return {\n ...state,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: { ...overlay, isOpen: true, isMounted: true },\n },\n };\n }\n case 'CLOSE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist or already closed\n if (overlay == null || !overlay.isOpen) {\n return state;\n }\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n ...state,\n current: currentOverlayId,\n overlayData: {\n ...state.overlayData,\n [action.overlayId]: {\n ...state.overlayData[action.overlayId],\n isOpen: false,\n },\n },\n };\n }\n case 'REMOVE': {\n const overlay = state.overlayData[action.overlayId];\n\n // ignore if the overlay don't exist\n if (overlay == null) {\n return state;\n }\n\n const remainingOverlays = state.overlayOrderList.filter((item) => item !== action.overlayId);\n if (state.overlayOrderList.length === remainingOverlays.length) {\n return state;\n }\n\n const copiedOverlayData = { ...state.overlayData };\n delete copiedOverlayData[action.overlayId];\n\n const currentOverlayId = determineCurrentOverlayId(state.overlayOrderList, state.overlayData, action.overlayId);\n\n return {\n current: currentOverlayId,\n overlayOrderList: remainingOverlays,\n overlayData: copiedOverlayData,\n };\n }\n case 'CLOSE_ALL': {\n // ignore if there is no overlay\n if (Object.keys(state.overlayData).length === 0) {\n return state;\n }\n\n return {\n ...state,\n current: null,\n overlayData: Object.keys(state.overlayData).reduce(\n (prev, curr) => ({\n ...prev,\n [curr]: {\n ...state.overlayData[curr],\n isOpen: false,\n } satisfies OverlayItem,\n }),\n {} satisfies Record<string, OverlayItem>\n ),\n };\n }\n case 'REMOVE_ALL': {\n return { current: null, overlayOrderList: [], overlayData: {} };\n }\n }\n}","import { createOverlayProvider } from '../context/provider';\n\nexport const { overlay, OverlayProvider, useCurrentOverlay, useOverlayData } = createOverlayProvider();\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function experimental_createOverlayContext() {\n return createOverlayProvider();\n}"],"mappings":"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","names":["useCallback","useEffect","memo","useEffect","jsx","memo","useEffect","_a","React","memo","useEffect","useState","View","StyleSheet","jsx","memo","useState","useEffect","styles","StyleSheet","View","React","React","useEffect","useEffect","overlayId","React","close","unmount","useCurrentOverlay","useOverlayData","overlay","BottomSheetModalProvider","jsx","overlay","useCurrentOverlay","useOverlayData","OverlayProvider","useCallback","overlayId","useEffect","BottomSheetModalProvider"]}
|