@0610studio/zs-ui 0.0.63 → 0.0.64
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/overlay/BottomSheetOverlay/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAO3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAIzD,iBAAS,kBAAkB,CAAC,EAC1B,eAAe,EACf,SAAS,EACT,OAAY,GACb,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/overlay/BottomSheetOverlay/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAO3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAIzD,iBAAS,kBAAkB,CAAC,EAC1B,eAAe,EACf,SAAS,EACT,OAAY,GACb,EAAE,oBAAoB,4BAqJtB;AAyBD,eAAe,kBAAkB,CAAC"}
|
|
@@ -4,19 +4,21 @@ import { useBottomSheet } from '../../model/useOverlay';
|
|
|
4
4
|
import Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
|
|
5
5
|
import ModalBackground from '../ui/ModalBackground';
|
|
6
6
|
import { useTheme } from '../../model';
|
|
7
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
8
|
-
const { width } = Dimensions.get('window');
|
|
7
|
+
import { useSafeAreaInsets, initialWindowMetrics } from 'react-native-safe-area-context';
|
|
8
|
+
const { width, height: windowHeight } = Dimensions.get('window');
|
|
9
9
|
function BottomSheetOverlay({ headerComponent, component, options = {}, }) {
|
|
10
10
|
const { isBackgroundTouchClose = true, marginHorizontal = 10, marginBottom = 10, padding = 14, } = options;
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const { bottomSheetVisible, setBottomSheetVisible, height } = useBottomSheet();
|
|
12
|
+
// 화면의 크기보다 높이가 높으면 화면의 크기로 제한
|
|
13
|
+
const maxHeight = Math.min((windowHeight - 30 - (initialWindowMetrics?.insets.bottom || 0) - (initialWindowMetrics?.insets.top || 0)), height);
|
|
14
|
+
const translateY = useSharedValue(maxHeight);
|
|
13
15
|
const translateX = useSharedValue(0);
|
|
14
|
-
const translateY = useSharedValue(height);
|
|
15
16
|
const scale = useSharedValue(1);
|
|
16
17
|
const { palette } = useTheme();
|
|
17
18
|
const { bottom } = useSafeAreaInsets();
|
|
18
19
|
const startX = useRef(0);
|
|
19
20
|
const startY = useRef(0);
|
|
21
|
+
const [localVisible, setLocalVisible] = useState(false);
|
|
20
22
|
// ** 소프트 키보드 핸들링
|
|
21
23
|
useEffect(() => {
|
|
22
24
|
const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
|
|
@@ -45,7 +47,7 @@ function BottomSheetOverlay({ headerComponent, component, options = {}, }) {
|
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
49
|
else {
|
|
48
|
-
translateY.value = withTiming(
|
|
50
|
+
translateY.value = withTiming(maxHeight + 100, { duration: 150 });
|
|
49
51
|
setTimeout(() => {
|
|
50
52
|
setLocalVisible(false);
|
|
51
53
|
}, 200);
|
|
@@ -83,8 +85,8 @@ function BottomSheetOverlay({ headerComponent, component, options = {}, }) {
|
|
|
83
85
|
onPanResponderRelease: (_, gestureState) => {
|
|
84
86
|
translateX.value = withTiming(0, { duration: 100 });
|
|
85
87
|
// 빠른 플리킹 제스처를 했을 때, 혹은 화면의 1/3 이상 내렸을 때, 닫기
|
|
86
|
-
if (gestureState.vy > 0.5 || translateY.value >
|
|
87
|
-
translateY.value = withTiming(
|
|
88
|
+
if (gestureState.vy > 0.5 || translateY.value > maxHeight / 3) {
|
|
89
|
+
translateY.value = withTiming(maxHeight + 100, { duration: 150 });
|
|
88
90
|
setBottomSheetVisible(false);
|
|
89
91
|
}
|
|
90
92
|
else {
|
|
@@ -107,7 +109,7 @@ function BottomSheetOverlay({ headerComponent, component, options = {}, }) {
|
|
|
107
109
|
styles.container,
|
|
108
110
|
{
|
|
109
111
|
width: width - marginHorizontal * 2,
|
|
110
|
-
height,
|
|
112
|
+
height: maxHeight,
|
|
111
113
|
marginHorizontal,
|
|
112
114
|
bottom: marginBottom + bottom,
|
|
113
115
|
backgroundColor: palette.background.base,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/overlay/BottomSheetOverlay/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useState, useRef } from 'react';\nimport { Dimensions, StyleSheet, View, PanResponder, Keyboard, Platform } from 'react-native';\nimport { useBottomSheet } from '../../model/useOverlay';\nimport Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';\nimport ModalBackground from '../ui/ModalBackground';\nimport { useTheme } from '../../model';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { ShowBottomSheetProps } from '../../model/types';\n\nconst { width } = Dimensions.get('window');\n\nfunction BottomSheetOverlay({\n headerComponent,\n component,\n options = {},\n}: ShowBottomSheetProps) {\n const {\n isBackgroundTouchClose = true,\n marginHorizontal = 10,\n marginBottom = 10,\n padding = 14,\n } = options;\n\n const [localVisible, setLocalVisible] = useState(false);\n const { bottomSheetVisible, setBottomSheetVisible, height, setHeight } = useBottomSheet();\n const translateX = useSharedValue(0);\n const translateY = useSharedValue(height);\n const scale = useSharedValue(1);\n const { palette } = useTheme();\n const { bottom } = useSafeAreaInsets();\n const startX = useRef(0);\n const startY = useRef(0);\n\n // ** 소프트 키보드 핸들링\n useEffect(() => {\n const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';\n const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';\n\n const keyboardShowSubscription = Keyboard.addListener(showEvent, (event) => {\n translateY.value = withTiming(Platform.OS === 'ios' ? (-event.endCoordinates.height + bottom) : 0, { duration: 300 });\n });\n\n const keyboardHideSubscription = Keyboard.addListener(hideEvent, () => {\n translateY.value = withTiming(0, { duration: 200 });\n });\n\n return () => {\n keyboardShowSubscription.remove();\n keyboardHideSubscription.remove();\n };\n }, []);\n\n useEffect(() => {\n if (bottomSheetVisible) {\n Keyboard.dismiss();\n setLocalVisible(true);\n translateY.value = withSpring(0, {\n damping: 50,\n stiffness: 300,\n mass: 0.7,\n velocity: 100,\n restDisplacementThreshold: 0.2,\n });\n } else {\n translateY.value = withTiming(height + 100, { duration: 150 });\n setTimeout(() => {\n setLocalVisible(false);\n }, 200);\n }\n }, [bottomSheetVisible]);\n\n const animatedStyles = useAnimatedStyle(() => {\n return {\n transform: [\n { translateY: translateY.value },\n { translateX: translateX.value },\n { scale: scale.value }\n ],\n };\n });\n\n const panResponder = useRef(\n PanResponder.create({\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: () => true,\n onPanResponderGrant: () => {\n Keyboard.dismiss();\n startX.current = translateX.value;\n startY.current = translateY.value;\n scale.value = withTiming(0.985, { duration: 200 });\n\n },\n onPanResponderMove: (_, gestureState) => {\n const newTranslateX = (startX.current + gestureState.dx) / 18;\n translateX.value = newTranslateX;\n\n const newTranslateY = startY.current + gestureState.dy;\n if (newTranslateY < 0) {\n translateY.value = newTranslateY / 18;\n } else {\n translateY.value = newTranslateY / 1.5;\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n translateX.value = withTiming(0, { duration: 100 });\n\n // 빠른 플리킹 제스처를 했을 때, 혹은 화면의 1/3 이상 내렸을 때, 닫기\n if (gestureState.vy > 0.5 || translateY.value > height / 3) {\n translateY.value = withTiming(height + 100, { duration: 150 });\n setBottomSheetVisible(false);\n } else {\n translateY.value = withTiming(0, { duration: 150 });\n }\n\n // 사이즈 원래대로 복귀\n scale.value = withSpring(1, {\n damping: 15,\n stiffness: 300\n });\n },\n })\n ).current;\n\n if (!localVisible) return null;\n\n return (\n <ModalBackground\n modalBgColor={palette.modalBgColor}\n onPress={() => {\n if (isBackgroundTouchClose) setBottomSheetVisible(false);\n }}\n >\n <Animated.View\n style={[\n styles.container,\n {\n width: width - marginHorizontal * 2,\n height,\n marginHorizontal,\n bottom: marginBottom + bottom,\n backgroundColor: palette.background.base,\n },\n animatedStyles,\n ]}\n >\n <View\n style={[\n styles.pressableView,\n { paddingHorizontal: padding, paddingBottom: padding },\n ]}\n >\n <View {...panResponder.panHandlers}>\n <View style={[styles.gestureBarContainer, { paddingBottom: padding }]}>\n <View style={[styles.gestureBar, { backgroundColor: palette.divider }]} />\n </View>\n {headerComponent}\n </View>\n\n {component}\n </View>\n </Animated.View>\n </ModalBackground>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n position: 'absolute',\n borderRadius: 26,\n overflow: 'hidden',\n },\n pressableView: {\n width: '100%',\n height: '100%',\n },\n gestureBarContainer: {\n width: '100%',\n paddingTop: 10,\n justifyContent: 'center',\n alignItems: 'center',\n },\n gestureBar: {\n width: 45,\n height: 3,\n borderRadius: 2,\n },\n});\n\nexport default BottomSheetOverlay;"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/overlay/BottomSheetOverlay/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useState, useRef } from 'react';\nimport { Dimensions, StyleSheet, View, PanResponder, Keyboard, Platform } from 'react-native';\nimport { useBottomSheet } from '../../model/useOverlay';\nimport Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';\nimport ModalBackground from '../ui/ModalBackground';\nimport { useTheme } from '../../model';\nimport { useSafeAreaInsets, initialWindowMetrics } from 'react-native-safe-area-context';\nimport { ShowBottomSheetProps } from '../../model/types';\n\nconst { width, height: windowHeight } = Dimensions.get('window');\n\nfunction BottomSheetOverlay({\n headerComponent,\n component,\n options = {},\n}: ShowBottomSheetProps) {\n const {\n isBackgroundTouchClose = true,\n marginHorizontal = 10,\n marginBottom = 10,\n padding = 14,\n } = options;\n const { bottomSheetVisible, setBottomSheetVisible, height } = useBottomSheet();\n // 화면의 크기보다 높이가 높으면 화면의 크기로 제한\n const maxHeight = Math.min((windowHeight - 30 - (initialWindowMetrics?.insets.bottom || 0) - (initialWindowMetrics?.insets.top || 0)), height);\n const translateY = useSharedValue(maxHeight);\n const translateX = useSharedValue(0);\n const scale = useSharedValue(1);\n const { palette } = useTheme();\n const { bottom } = useSafeAreaInsets();\n const startX = useRef(0);\n const startY = useRef(0);\n const [localVisible, setLocalVisible] = useState(false);\n\n // ** 소프트 키보드 핸들링\n useEffect(() => {\n const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';\n const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';\n\n const keyboardShowSubscription = Keyboard.addListener(showEvent, (event) => {\n translateY.value = withTiming(Platform.OS === 'ios' ? (-event.endCoordinates.height + bottom) : 0, { duration: 300 });\n });\n\n const keyboardHideSubscription = Keyboard.addListener(hideEvent, () => {\n translateY.value = withTiming(0, { duration: 200 });\n });\n\n return () => {\n keyboardShowSubscription.remove();\n keyboardHideSubscription.remove();\n };\n }, []);\n\n useEffect(() => {\n if (bottomSheetVisible) {\n Keyboard.dismiss();\n setLocalVisible(true);\n translateY.value = withSpring(0, {\n damping: 50,\n stiffness: 300,\n mass: 0.7,\n velocity: 100,\n restDisplacementThreshold: 0.2,\n });\n } else {\n translateY.value = withTiming(maxHeight + 100, { duration: 150 });\n setTimeout(() => {\n setLocalVisible(false);\n }, 200);\n }\n }, [bottomSheetVisible]);\n\n const animatedStyles = useAnimatedStyle(() => {\n return {\n transform: [\n { translateY: translateY.value },\n { translateX: translateX.value },\n { scale: scale.value }\n ],\n };\n });\n\n const panResponder = useRef(\n PanResponder.create({\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: () => true,\n onPanResponderGrant: () => {\n Keyboard.dismiss();\n startX.current = translateX.value;\n startY.current = translateY.value;\n scale.value = withTiming(0.985, { duration: 200 });\n\n },\n onPanResponderMove: (_, gestureState) => {\n const newTranslateX = (startX.current + gestureState.dx) / 18;\n translateX.value = newTranslateX;\n\n const newTranslateY = startY.current + gestureState.dy;\n if (newTranslateY < 0) {\n translateY.value = newTranslateY / 18;\n } else {\n translateY.value = newTranslateY / 1.5;\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n translateX.value = withTiming(0, { duration: 100 });\n\n // 빠른 플리킹 제스처를 했을 때, 혹은 화면의 1/3 이상 내렸을 때, 닫기\n if (gestureState.vy > 0.5 || translateY.value > maxHeight / 3) {\n translateY.value = withTiming(maxHeight + 100, { duration: 150 });\n setBottomSheetVisible(false);\n } else {\n translateY.value = withTiming(0, { duration: 150 });\n }\n\n // 사이즈 원래대로 복귀\n scale.value = withSpring(1, {\n damping: 15,\n stiffness: 300\n });\n },\n })\n ).current;\n\n if (!localVisible) return null;\n\n return (\n <ModalBackground\n modalBgColor={palette.modalBgColor}\n onPress={() => {\n if (isBackgroundTouchClose) setBottomSheetVisible(false);\n }}\n >\n <Animated.View\n style={[\n styles.container,\n {\n width: width - marginHorizontal * 2,\n height: maxHeight,\n marginHorizontal,\n bottom: marginBottom + bottom,\n backgroundColor: palette.background.base,\n },\n animatedStyles,\n ]}\n >\n <View\n style={[\n styles.pressableView,\n { paddingHorizontal: padding, paddingBottom: padding },\n ]}\n >\n <View {...panResponder.panHandlers}>\n <View style={[styles.gestureBarContainer, { paddingBottom: padding }]}>\n <View style={[styles.gestureBar, { backgroundColor: palette.divider }]} />\n </View>\n {headerComponent}\n </View>\n\n {component}\n </View>\n </Animated.View>\n </ModalBackground>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n position: 'absolute',\n borderRadius: 26,\n overflow: 'hidden',\n },\n pressableView: {\n width: '100%',\n height: '100%',\n },\n gestureBarContainer: {\n width: '100%',\n paddingTop: 10,\n justifyContent: 'center',\n alignItems: 'center',\n },\n gestureBar: {\n width: 45,\n height: 3,\n borderRadius: 2,\n },\n});\n\nexport default BottomSheetOverlay;"]}
|