@mustmove/overlay-kit-rn 1.0.23 → 1.0.25

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 CHANGED
@@ -110,11 +110,16 @@ var ContentBottomSheetController = (0, import_react2.memo)(
110
110
  overlayId,
111
111
  overlayDispatch,
112
112
  controller: Controller,
113
+ overlayOrderList,
113
114
  options = {}
114
115
  }) => {
115
116
  const bottomSheetRef = (0, import_react2.useRef)(null);
116
117
  const reducedMotion = (0, import_react_native_reanimated.useReducedMotion)();
117
118
  const [keyboardHeight, setKeyboardHeight] = (0, import_react2.useState)(0);
119
+ const getZIndex = () => {
120
+ const index = overlayOrderList.indexOf(overlayId);
121
+ return 9999 + index;
122
+ };
118
123
  const _a = options, {
119
124
  snapPoints,
120
125
  enablePanDownToClose = true,
@@ -186,12 +191,12 @@ var ContentBottomSheetController = (0, import_react2.memo)(
186
191
  [backdropOpacity, keyboardHeight]
187
192
  );
188
193
  const handleSheetChange = (0, import_react2.useCallback)((index) => {
189
- console.log("handleSheetChange", index);
190
194
  }, []);
191
195
  if (!isOpen) return null;
192
196
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
193
197
  import_bottom_sheet.default,
194
198
  {
199
+ style: [{ zIndex: getZIndex() }],
195
200
  ref: bottomSheetRef,
196
201
  onChange: handleSheetChange,
197
202
  android_keyboardInputMode: androidKeyboardInputMode,
@@ -219,13 +224,10 @@ var ContentBottomSheetController = (0, import_react2.memo)(
219
224
  ],
220
225
  enableDynamicSizing,
221
226
  animateOnMount: !reducedMotion,
222
- children: import_react2.default.isValidElement(Controller) ? import_react2.default.cloneElement(
223
- Controller,
224
- {
225
- close: () => overlayDispatch({ type: "CLOSE", overlayId }),
226
- unmount: () => overlayDispatch({ type: "REMOVE", overlayId })
227
- }
228
- ) : import_react2.default.createElement(Controller, __spreadValues({
227
+ children: import_react2.default.isValidElement(Controller) ? import_react2.default.cloneElement(Controller, {
228
+ close: () => overlayDispatch({ type: "CLOSE", overlayId }),
229
+ unmount: () => overlayDispatch({ type: "REMOVE", overlayId })
230
+ }) : import_react2.default.createElement(Controller, __spreadValues({
229
231
  isOpen,
230
232
  overlayId,
231
233
  snapPoints,
@@ -250,6 +252,7 @@ var ContentModalController = (0, import_react3.memo)(
250
252
  overlayId,
251
253
  overlayDispatch,
252
254
  controller: Controller,
255
+ overlayOrderList,
253
256
  options = {}
254
257
  }) => {
255
258
  const {
@@ -260,6 +263,10 @@ var ContentModalController = (0, import_react3.memo)(
260
263
  } = options;
261
264
  const [backdropAnimation] = (0, import_react3.useState)(new import_react_native2.Animated.Value(0));
262
265
  const [contentAnimation] = (0, import_react3.useState)(new import_react_native2.Animated.Value(0));
266
+ const getZIndex = () => {
267
+ const index = overlayOrderList.indexOf(overlayId);
268
+ return 1e3 + index;
269
+ };
263
270
  (0, import_react3.useEffect)(() => {
264
271
  if (isOpen) {
265
272
  setImmediate(() => {
@@ -316,9 +323,7 @@ var ContentModalController = (0, import_react3.memo)(
316
323
  }
317
324
  };
318
325
  const getContentAnimationStyle = () => {
319
- const baseOpacity = {
320
- opacity: contentAnimation
321
- };
326
+ const baseOpacity = { opacity: contentAnimation };
322
327
  switch (modalType) {
323
328
  case "bottom":
324
329
  return __spreadProps(__spreadValues({}, baseOpacity), {
@@ -382,14 +387,10 @@ var ContentModalController = (0, import_react3.memo)(
382
387
  };
383
388
  if (!isOpen) return null;
384
389
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
385
- import_react_native2.Modal,
390
+ import_react_native2.View,
386
391
  {
387
- visible: isOpen,
388
- transparent: true,
389
- animationType: "none",
390
- onRequestClose: handleClose,
391
- statusBarTranslucent: true,
392
- presentationStyle: "overFullScreen",
392
+ style: [styles.absoluteContainer, { zIndex: getZIndex() }],
393
+ pointerEvents: "box-none",
393
394
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native2.Pressable, { style: import_react_native2.StyleSheet.absoluteFill, onPress: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
394
395
  import_react_native2.Animated.View,
395
396
  {
@@ -431,6 +432,7 @@ var ContentModalController = (0, import_react3.memo)(
431
432
  }
432
433
  );
433
434
  var styles = import_react_native2.StyleSheet.create({
435
+ absoluteContainer: __spreadValues({}, import_react_native2.StyleSheet.absoluteFillObject),
434
436
  backdrop: __spreadValues({}, import_react_native2.StyleSheet.absoluteFillObject),
435
437
  centerContainer: {
436
438
  flex: 1,
@@ -808,7 +810,7 @@ function createOverlayProvider() {
808
810
  overlayDispatch({ type: "REMOVE_ALL" });
809
811
  };
810
812
  }, []);
811
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_gesture_handler.GestureHandlerRootView, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_bottom_sheet2.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(OverlayContextProvider, { value: overlayState, children: [
813
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_gesture_handler.GestureHandlerRootView, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_bottom_sheet2.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(OverlayContextProvider, { value: overlayState, children: [
812
814
  children,
813
815
  overlayState.overlayOrderList.map((item) => {
814
816
  const overlayItem = overlayState.overlayData[item];
@@ -821,20 +823,35 @@ function createOverlayProvider() {
821
823
  options
822
824
  } = overlayItem;
823
825
  if (overlayType === "bottomSheet") {
826
+ const sameTypeOverlays = overlayState.overlayOrderList.filter(
827
+ (id) => {
828
+ var _a2, _b;
829
+ return ((_a2 = overlayState.overlayData[id]) == null ? void 0 : _a2.overlayType) === "bottomSheet" && ((_b = overlayState.overlayData[id]) == null ? void 0 : _b.isOpen);
830
+ }
831
+ );
832
+ const isTopBottomSheet = sameTypeOverlays[sameTypeOverlays.length - 1] === currentOverlayId;
833
+ const shouldShow = isOpen && isTopBottomSheet;
824
834
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
825
835
  ContentBottomSheetController,
826
836
  {
827
- isOpen,
837
+ isOpen: shouldShow,
828
838
  controller: Controller,
829
839
  overlayId: currentOverlayId,
830
840
  overlayDispatch,
841
+ overlayOrderList: overlayState.overlayOrderList,
831
842
  options
832
843
  },
833
844
  componentKey
834
845
  );
835
846
  } else if (overlayType === "modal") {
836
- const isCurrentModal = overlayState.current === currentOverlayId;
837
- const shouldShow = isOpen && isCurrentModal;
847
+ const sameTypeOverlays = overlayState.overlayOrderList.filter(
848
+ (id) => {
849
+ var _a2, _b;
850
+ return ((_a2 = overlayState.overlayData[id]) == null ? void 0 : _a2.overlayType) === "modal" && ((_b = overlayState.overlayData[id]) == null ? void 0 : _b.isOpen);
851
+ }
852
+ );
853
+ const isTopModal = sameTypeOverlays[sameTypeOverlays.length - 1] === currentOverlayId;
854
+ const shouldShow = isOpen && isTopModal;
838
855
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
839
856
  ContentModalController,
840
857
  {
@@ -842,6 +859,7 @@ function createOverlayProvider() {
842
859
  controller: Controller,
843
860
  overlayId: currentOverlayId,
844
861
  overlayDispatch,
862
+ overlayOrderList: overlayState.overlayOrderList,
845
863
  options
846
864
  },
847
865
  componentKey
@@ -859,7 +877,7 @@ function createOverlayProvider() {
859
877
  );
860
878
  }
861
879
  })
862
- ] }) }) });
880
+ ] }) }) }) });
863
881
  }
864
882
  return {
865
883
  overlay: overlay2,
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/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 | React.ReactElement;\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 {React.isValidElement(Controller)\n ? React.cloneElement(\n Controller as React.ReactElement<any>,\n {\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n }\n )\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n snapPoints,\n enablePanDownToClose,\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n keyboardHeight,\n ...restOptions,\n })}\n </BottomSheet>\n );\n }\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","React","import_react","import_react_native","import_jsx_runtime","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"]}
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 <>\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 // 바텀시트는 같은 타입 중 최상위만 표시\n const sameTypeOverlays = overlayState.overlayOrderList.filter(\n (id) =>\n overlayState.overlayData[id]?.overlayType ===\n \"bottomSheet\" && overlayState.overlayData[id]?.isOpen\n );\n const isTopBottomSheet =\n sameTypeOverlays[sameTypeOverlays.length - 1] ===\n currentOverlayId;\n const shouldShow = isOpen && isTopBottomSheet;\n\n return (\n <ContentBottomSheetController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n overlayOrderList={overlayState.overlayOrderList}\n options={options}\n />\n );\n } else if (overlayType === \"modal\") {\n // 모달은 같은 타입 중 최상위만 표시\n const sameTypeOverlays = overlayState.overlayOrderList.filter(\n (id) =>\n overlayState.overlayData[id]?.overlayType === \"modal\" &&\n overlayState.overlayData[id]?.isOpen\n );\n const isTopModal =\n sameTypeOverlays[sameTypeOverlays.length - 1] ===\n currentOverlayId;\n const shouldShow = isOpen && isTopModal;\n\n return (\n <ContentModalController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n overlayOrderList={overlayState.overlayOrderList}\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\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 | React.ReactElement;\n overlayOrderList: string[];\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 overlayOrderList,\n options = {},\n }: ContentBottomSheetControllerProps) => {\n const bottomSheetRef = useRef<BottomSheet>(null);\n const reducedMotion = useReducedMotion();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n const getZIndex = () => {\n const index = overlayOrderList.indexOf(overlayId);\n // bottomSheet는 항상 modal보다 앞에 나오도록 훨씬 높은 zIndex 사용\n return 9999 + index;\n };\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\n if (!isOpen) return null;\n\n return (\n <BottomSheet\n style={[{ zIndex: getZIndex() }]}\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 {React.isValidElement(Controller)\n ? React.cloneElement(Controller as React.ReactElement<any>, {\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n })\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n snapPoints,\n enablePanDownToClose,\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n keyboardHeight,\n ...restOptions,\n })}\n </BottomSheet>\n );\n }\n);\n","// modal-controller.tsx\nimport React, { type FC, memo, useEffect, useState } from \"react\";\nimport {\n View,\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 overlayOrderList: string[];\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 overlayOrderList,\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 const getZIndex = () => {\n const index = overlayOrderList.indexOf(overlayId);\n return 1000 + index;\n };\n\n useEffect(() => {\n if (isOpen) {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\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 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:\n return styles.centerContainer;\n }\n };\n\n const getContentAnimationStyle = () => {\n const baseOpacity = { opacity: contentAnimation };\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:\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 if (!isOpen) return null;\n\n return (\n <View\n style={[styles.absoluteContainer, { zIndex: getZIndex() }]}\n pointerEvents=\"box-none\"\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 </View>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n absoluteContainer: {\n ...StyleSheet.absoluteFillObject,\n },\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","React","import_react","import_react_native","import_jsx_runtime","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","_a"]}
package/dist/index.mjs CHANGED
@@ -87,11 +87,16 @@ var ContentBottomSheetController = memo2(
87
87
  overlayId,
88
88
  overlayDispatch,
89
89
  controller: Controller,
90
+ overlayOrderList,
90
91
  options = {}
91
92
  }) => {
92
93
  const bottomSheetRef = useRef(null);
93
94
  const reducedMotion = useReducedMotion();
94
95
  const [keyboardHeight, setKeyboardHeight] = useState(0);
96
+ const getZIndex = () => {
97
+ const index = overlayOrderList.indexOf(overlayId);
98
+ return 9999 + index;
99
+ };
95
100
  const _a = options, {
96
101
  snapPoints,
97
102
  enablePanDownToClose = true,
@@ -163,12 +168,12 @@ var ContentBottomSheetController = memo2(
163
168
  [backdropOpacity, keyboardHeight]
164
169
  );
165
170
  const handleSheetChange = useCallback((index) => {
166
- console.log("handleSheetChange", index);
167
171
  }, []);
168
172
  if (!isOpen) return null;
169
173
  return /* @__PURE__ */ jsx2(
170
174
  BottomSheet,
171
175
  {
176
+ style: [{ zIndex: getZIndex() }],
172
177
  ref: bottomSheetRef,
173
178
  onChange: handleSheetChange,
174
179
  android_keyboardInputMode: androidKeyboardInputMode,
@@ -196,13 +201,10 @@ var ContentBottomSheetController = memo2(
196
201
  ],
197
202
  enableDynamicSizing,
198
203
  animateOnMount: !reducedMotion,
199
- children: React2.isValidElement(Controller) ? React2.cloneElement(
200
- Controller,
201
- {
202
- close: () => overlayDispatch({ type: "CLOSE", overlayId }),
203
- unmount: () => overlayDispatch({ type: "REMOVE", overlayId })
204
- }
205
- ) : React2.createElement(Controller, __spreadValues({
204
+ children: React2.isValidElement(Controller) ? React2.cloneElement(Controller, {
205
+ close: () => overlayDispatch({ type: "CLOSE", overlayId }),
206
+ unmount: () => overlayDispatch({ type: "REMOVE", overlayId })
207
+ }) : React2.createElement(Controller, __spreadValues({
206
208
  isOpen,
207
209
  overlayId,
208
210
  snapPoints,
@@ -219,7 +221,6 @@ var ContentBottomSheetController = memo2(
219
221
  // src/context/provider/modal-controller.tsx
220
222
  import React3, { memo as memo3, useEffect as useEffect3, useState as useState2 } from "react";
221
223
  import {
222
- Modal,
223
224
  View as View2,
224
225
  Animated,
225
226
  StyleSheet as StyleSheet2,
@@ -234,6 +235,7 @@ var ContentModalController = memo3(
234
235
  overlayId,
235
236
  overlayDispatch,
236
237
  controller: Controller,
238
+ overlayOrderList,
237
239
  options = {}
238
240
  }) => {
239
241
  const {
@@ -244,6 +246,10 @@ var ContentModalController = memo3(
244
246
  } = options;
245
247
  const [backdropAnimation] = useState2(new Animated.Value(0));
246
248
  const [contentAnimation] = useState2(new Animated.Value(0));
249
+ const getZIndex = () => {
250
+ const index = overlayOrderList.indexOf(overlayId);
251
+ return 1e3 + index;
252
+ };
247
253
  useEffect3(() => {
248
254
  if (isOpen) {
249
255
  setImmediate(() => {
@@ -300,9 +306,7 @@ var ContentModalController = memo3(
300
306
  }
301
307
  };
302
308
  const getContentAnimationStyle = () => {
303
- const baseOpacity = {
304
- opacity: contentAnimation
305
- };
309
+ const baseOpacity = { opacity: contentAnimation };
306
310
  switch (modalType) {
307
311
  case "bottom":
308
312
  return __spreadProps(__spreadValues({}, baseOpacity), {
@@ -366,14 +370,10 @@ var ContentModalController = memo3(
366
370
  };
367
371
  if (!isOpen) return null;
368
372
  return /* @__PURE__ */ jsx3(
369
- Modal,
373
+ View2,
370
374
  {
371
- visible: isOpen,
372
- transparent: true,
373
- animationType: "none",
374
- onRequestClose: handleClose,
375
- statusBarTranslucent: true,
376
- presentationStyle: "overFullScreen",
375
+ style: [styles.absoluteContainer, { zIndex: getZIndex() }],
376
+ pointerEvents: "box-none",
377
377
  children: /* @__PURE__ */ jsx3(Pressable, { style: StyleSheet2.absoluteFill, onPress: handleClose, children: /* @__PURE__ */ jsx3(
378
378
  Animated.View,
379
379
  {
@@ -415,6 +415,7 @@ var ContentModalController = memo3(
415
415
  }
416
416
  );
417
417
  var styles = StyleSheet2.create({
418
+ absoluteContainer: __spreadValues({}, StyleSheet2.absoluteFillObject),
418
419
  backdrop: __spreadValues({}, StyleSheet2.absoluteFillObject),
419
420
  centerContainer: {
420
421
  flex: 1,
@@ -734,7 +735,7 @@ function overlayReducer(state, action) {
734
735
  // src/context/provider/index.tsx
735
736
  import { GestureHandlerRootView } from "react-native-gesture-handler";
736
737
  import { BottomSheetModalProvider as BottomSheetModalProvider2 } from "@gorhom/bottom-sheet";
737
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
738
+ import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
738
739
  function createOverlayProvider() {
739
740
  const overlayId = randomId();
740
741
  const _a = createOverlay(overlayId), { useOverlayEvent } = _a, overlay2 = __objRest(_a, ["useOverlayEvent"]);
@@ -792,7 +793,7 @@ function createOverlayProvider() {
792
793
  overlayDispatch({ type: "REMOVE_ALL" });
793
794
  };
794
795
  }, []);
795
- return /* @__PURE__ */ jsx4(GestureHandlerRootView, { style: { flex: 1 }, children: /* @__PURE__ */ jsx4(BottomSheetModalProvider2, { children: /* @__PURE__ */ jsxs(OverlayContextProvider, { value: overlayState, children: [
796
+ return /* @__PURE__ */ jsx4(Fragment, { children: /* @__PURE__ */ jsx4(GestureHandlerRootView, { style: { flex: 1 }, children: /* @__PURE__ */ jsx4(BottomSheetModalProvider2, { children: /* @__PURE__ */ jsxs(OverlayContextProvider, { value: overlayState, children: [
796
797
  children,
797
798
  overlayState.overlayOrderList.map((item) => {
798
799
  const overlayItem = overlayState.overlayData[item];
@@ -805,20 +806,35 @@ function createOverlayProvider() {
805
806
  options
806
807
  } = overlayItem;
807
808
  if (overlayType === "bottomSheet") {
809
+ const sameTypeOverlays = overlayState.overlayOrderList.filter(
810
+ (id) => {
811
+ var _a2, _b;
812
+ return ((_a2 = overlayState.overlayData[id]) == null ? void 0 : _a2.overlayType) === "bottomSheet" && ((_b = overlayState.overlayData[id]) == null ? void 0 : _b.isOpen);
813
+ }
814
+ );
815
+ const isTopBottomSheet = sameTypeOverlays[sameTypeOverlays.length - 1] === currentOverlayId;
816
+ const shouldShow = isOpen && isTopBottomSheet;
808
817
  return /* @__PURE__ */ jsx4(
809
818
  ContentBottomSheetController,
810
819
  {
811
- isOpen,
820
+ isOpen: shouldShow,
812
821
  controller: Controller,
813
822
  overlayId: currentOverlayId,
814
823
  overlayDispatch,
824
+ overlayOrderList: overlayState.overlayOrderList,
815
825
  options
816
826
  },
817
827
  componentKey
818
828
  );
819
829
  } else if (overlayType === "modal") {
820
- const isCurrentModal = overlayState.current === currentOverlayId;
821
- const shouldShow = isOpen && isCurrentModal;
830
+ const sameTypeOverlays = overlayState.overlayOrderList.filter(
831
+ (id) => {
832
+ var _a2, _b;
833
+ return ((_a2 = overlayState.overlayData[id]) == null ? void 0 : _a2.overlayType) === "modal" && ((_b = overlayState.overlayData[id]) == null ? void 0 : _b.isOpen);
834
+ }
835
+ );
836
+ const isTopModal = sameTypeOverlays[sameTypeOverlays.length - 1] === currentOverlayId;
837
+ const shouldShow = isOpen && isTopModal;
822
838
  return /* @__PURE__ */ jsx4(
823
839
  ContentModalController,
824
840
  {
@@ -826,6 +842,7 @@ function createOverlayProvider() {
826
842
  controller: Controller,
827
843
  overlayId: currentOverlayId,
828
844
  overlayDispatch,
845
+ overlayOrderList: overlayState.overlayOrderList,
829
846
  options
830
847
  },
831
848
  componentKey
@@ -843,7 +860,7 @@ function createOverlayProvider() {
843
860
  );
844
861
  }
845
862
  })
846
- ] }) }) });
863
+ ] }) }) }) });
847
864
  }
848
865
  return {
849
866
  overlay: overlay2,
@@ -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/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 | React.ReactElement;\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 {React.isValidElement(Controller)\n ? React.cloneElement(\n Controller as React.ReactElement<any>,\n {\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n }\n )\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n snapPoints,\n enablePanDownToClose,\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n keyboardHeight,\n ...restOptions,\n })}\n </BottomSheet>\n );\n }\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","React","memo","useEffect","jsx","memo","useEffect","_a","React","React","memo","useEffect","useState","View","StyleSheet","jsx","memo","useState","useEffect","StyleSheet","View","React","React","useEffect","useEffect","overlayId","React","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 <>\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 // 바텀시트는 같은 타입 중 최상위만 표시\n const sameTypeOverlays = overlayState.overlayOrderList.filter(\n (id) =>\n overlayState.overlayData[id]?.overlayType ===\n \"bottomSheet\" && overlayState.overlayData[id]?.isOpen\n );\n const isTopBottomSheet =\n sameTypeOverlays[sameTypeOverlays.length - 1] ===\n currentOverlayId;\n const shouldShow = isOpen && isTopBottomSheet;\n\n return (\n <ContentBottomSheetController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n overlayOrderList={overlayState.overlayOrderList}\n options={options}\n />\n );\n } else if (overlayType === \"modal\") {\n // 모달은 같은 타입 중 최상위만 표시\n const sameTypeOverlays = overlayState.overlayOrderList.filter(\n (id) =>\n overlayState.overlayData[id]?.overlayType === \"modal\" &&\n overlayState.overlayData[id]?.isOpen\n );\n const isTopModal =\n sameTypeOverlays[sameTypeOverlays.length - 1] ===\n currentOverlayId;\n const shouldShow = isOpen && isTopModal;\n\n return (\n <ContentModalController\n key={componentKey}\n isOpen={shouldShow}\n controller={Controller as any}\n overlayId={currentOverlayId}\n overlayDispatch={overlayDispatch}\n overlayOrderList={overlayState.overlayOrderList}\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\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 | React.ReactElement;\n overlayOrderList: string[];\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 overlayOrderList,\n options = {},\n }: ContentBottomSheetControllerProps) => {\n const bottomSheetRef = useRef<BottomSheet>(null);\n const reducedMotion = useReducedMotion();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n const getZIndex = () => {\n const index = overlayOrderList.indexOf(overlayId);\n // bottomSheet는 항상 modal보다 앞에 나오도록 훨씬 높은 zIndex 사용\n return 9999 + index;\n };\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\n if (!isOpen) return null;\n\n return (\n <BottomSheet\n style={[{ zIndex: getZIndex() }]}\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 {React.isValidElement(Controller)\n ? React.cloneElement(Controller as React.ReactElement<any>, {\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n })\n : React.createElement(Controller as any, {\n isOpen,\n overlayId,\n snapPoints,\n enablePanDownToClose,\n close: () => overlayDispatch({ type: \"CLOSE\", overlayId }),\n unmount: () => overlayDispatch({ type: \"REMOVE\", overlayId }),\n keyboardHeight,\n ...restOptions,\n })}\n </BottomSheet>\n );\n }\n);\n","// modal-controller.tsx\nimport React, { type FC, memo, useEffect, useState } from \"react\";\nimport {\n View,\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 overlayOrderList: string[];\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 overlayOrderList,\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 const getZIndex = () => {\n const index = overlayOrderList.indexOf(overlayId);\n return 1000 + index;\n };\n\n useEffect(() => {\n if (isOpen) {\n setImmediate(() => {\n overlayDispatch({ type: \"OPEN\", overlayId });\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 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:\n return styles.centerContainer;\n }\n };\n\n const getContentAnimationStyle = () => {\n const baseOpacity = { opacity: contentAnimation };\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:\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 if (!isOpen) return null;\n\n return (\n <View\n style={[styles.absoluteContainer, { zIndex: getZIndex() }]}\n pointerEvents=\"box-none\"\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 </View>\n );\n }\n);\n\nconst styles = StyleSheet.create({\n absoluteContainer: {\n ...StyleSheet.absoluteFillObject,\n },\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","React","memo","useEffect","jsx","memo","useEffect","_a","React","React","memo","useEffect","useState","View","StyleSheet","jsx","memo","useState","useEffect","View","StyleSheet","React","React","useEffect","useEffect","overlayId","React","close","unmount","useCurrentOverlay","useOverlayData","overlay","BottomSheetModalProvider","jsx","overlay","useCurrentOverlay","useOverlayData","OverlayProvider","useCallback","overlayId","useEffect","BottomSheetModalProvider","_a"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mustmove/overlay-kit-rn",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "React Native overlay management library",
5
5
  "main": "dist/index.js",
6
6
  "react-native": "dist/index.js",
@@ -34,21 +34,25 @@
34
34
  "homepage": "https://github.com/from.deuk/overlay-kit-rn#readme",
35
35
  "license": "MIT",
36
36
  "peerDependencies": {
37
+ "@gorhom/bottom-sheet": ">=5",
37
38
  "react": "18 || 19",
38
39
  "react-native": ">=0.72",
39
- "react-native-reanimated": ">=3",
40
40
  "react-native-gesture-handler": ">=2",
41
- "@gorhom/bottom-sheet": ">=5",
42
- "react-native-worklets": ">=0.4.0"
41
+ "react-native-portalize": ">=1.0.0",
42
+ "react-native-reanimated": ">=3",
43
+ "react-native-worklets": ">=0.4.0",
44
+ "@gorhom/portal": ">=1.0.0"
43
45
  },
44
46
  "devDependencies": {
45
- "tsup": "^8",
46
- "typescript": "^5.4",
47
- "react-native": "0.81.0",
48
- "@types/react": "^19.1.5",
49
47
  "@gorhom/bottom-sheet": "^5.0.0",
50
- "react-native-reanimated": "^4.0.2",
48
+ "@types/react": "^19.1.5",
49
+ "react-native": "0.81.0",
51
50
  "react-native-gesture-handler": "^2.28.0",
52
- "react-native-worklets": "^0.4.1"
51
+ "react-native-portalize": "^1.0.7",
52
+ "react-native-reanimated": "^4.0.2",
53
+ "react-native-worklets": "^0.4.1",
54
+ "tsup": "^8",
55
+ "typescript": "^5.4",
56
+ "@gorhom/portal": "^1.0.14"
53
57
  }
54
58
  }