@0610studio/zs-ui 0.7.6 → 0.7.7

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.
@@ -15,7 +15,7 @@ function ZSAboveKeyboard({ keyboardShowOffset = 0, keyboardHideOffset = 0, child
15
15
  useEffect(() => {
16
16
  const keyboardShowSubscription = Keyboard.addListener(showEvent, (event) => {
17
17
  // 키보드 바로 위에 위치하도록 계산
18
- const topValue = screenHeight - event.endCoordinates.height - componentHeight - keyboardShowOffset - 0;
18
+ const topValue = screenHeight - event.endCoordinates.height - componentHeight - keyboardShowOffset - statusBarHeight;
19
19
  setTopValue(topValue);
20
20
  setIsKeyboardVisible(true);
21
21
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/ZSAboveKeyboard/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { Keyboard, Platform, StyleSheet, Dimensions, View, StatusBar, LayoutChangeEvent } from 'react-native';\nimport { Z_INDEX_VALUE } from '../../model/utils';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { ZSPortal } from '../../overlay';\n\nconst screenHeight = Dimensions.get('window').height;\nconst showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';\nconst hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';\n\ninterface Props {\n children: React.ReactNode;\n keyboardShowOffset?: number;\n keyboardHideOffset?: number;\n handleLayoutHeight?: (height: number) => void;\n}\n\nfunction ZSAboveKeyboard({\n keyboardShowOffset = 0,\n keyboardHideOffset = 0,\n children,\n handleLayoutHeight,\n}: Props) {\n const [topValue, setTopValue] = useState(0);\n const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);\n const [componentHeight, setComponentHeight] = useState(0);\n const { bottom } = useSafeAreaInsets();\n const statusBarHeight = StatusBar.currentHeight || 0;\n\n useEffect(() => {\n const keyboardShowSubscription = Keyboard.addListener(showEvent, (event) => {\n // 키보드 바로 위에 위치하도록 계산\n const topValue = screenHeight - event.endCoordinates.height - componentHeight - keyboardShowOffset - 0;\n setTopValue(topValue);\n setIsKeyboardVisible(true);\n });\n\n const keyboardHideSubscription = Keyboard.addListener(hideEvent, () => {\n setTopValue(0);\n setIsKeyboardVisible(false);\n });\n\n return () => {\n keyboardShowSubscription.remove();\n keyboardHideSubscription.remove();\n };\n }, [componentHeight]);\n\n const handleLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setComponentHeight(height);\n handleLayoutHeight?.(height);\n };\n\n return (\n <ZSPortal>\n <View style={[styles.container, isKeyboardVisible ? { top: topValue } : { bottom: keyboardHideOffset + bottom }]}>\n <View onLayout={handleLayout}>\n {children}\n </View>\n </View>\n </ZSPortal>\n );\n}\n\nexport default ZSAboveKeyboard;\n\nconst styles = StyleSheet.create({\n container: {\n position: 'absolute',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: Z_INDEX_VALUE.ABOVE_KEYBOARD,\n width: '100%',\n },\n});\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/ZSAboveKeyboard/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { Keyboard, Platform, StyleSheet, Dimensions, View, StatusBar, LayoutChangeEvent } from 'react-native';\nimport { Z_INDEX_VALUE } from '../../model/utils';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { ZSPortal } from '../../overlay';\n\nconst screenHeight = Dimensions.get('window').height;\nconst showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';\nconst hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';\n\ninterface Props {\n children: React.ReactNode;\n keyboardShowOffset?: number;\n keyboardHideOffset?: number;\n handleLayoutHeight?: (height: number) => void;\n}\n\nfunction ZSAboveKeyboard({\n keyboardShowOffset = 0,\n keyboardHideOffset = 0,\n children,\n handleLayoutHeight,\n}: Props) {\n const [topValue, setTopValue] = useState(0);\n const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);\n const [componentHeight, setComponentHeight] = useState(0);\n const { bottom } = useSafeAreaInsets();\n const statusBarHeight = StatusBar.currentHeight || 0;\n\n useEffect(() => {\n const keyboardShowSubscription = Keyboard.addListener(showEvent, (event) => {\n // 키보드 바로 위에 위치하도록 계산\n const topValue = screenHeight - event.endCoordinates.height - componentHeight - keyboardShowOffset - statusBarHeight;\n setTopValue(topValue);\n setIsKeyboardVisible(true);\n });\n\n const keyboardHideSubscription = Keyboard.addListener(hideEvent, () => {\n setTopValue(0);\n setIsKeyboardVisible(false);\n });\n\n return () => {\n keyboardShowSubscription.remove();\n keyboardHideSubscription.remove();\n };\n }, [componentHeight]);\n\n const handleLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setComponentHeight(height);\n handleLayoutHeight?.(height);\n };\n\n return (\n <ZSPortal>\n <View style={[styles.container, isKeyboardVisible ? { top: topValue } : { bottom: keyboardHideOffset + bottom }]}>\n <View onLayout={handleLayout}>\n {children}\n </View>\n </View>\n </ZSPortal>\n );\n}\n\nexport default ZSAboveKeyboard;\n\nconst styles = StyleSheet.create({\n container: {\n position: 'absolute',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: Z_INDEX_VALUE.ABOVE_KEYBOARD,\n width: '100%',\n },\n});\n"]}
@@ -62,9 +62,9 @@ const ZSContainer = forwardRef(function ZSContainer({ backgroundColor, statusBar
62
62
  const scrollContentStyle = useMemo(() => [
63
63
  styles.scrollContainerStyle,
64
64
  {
65
- paddingBottom: keyboardHeight ? (IS_IOS ? keyboardHeight : keyboardScrollExtraOffset) : 0
65
+ paddingBottom: keyboardHeight ? (IS_IOS ? keyboardHeight : 0) : 0
66
66
  }
67
- ], [keyboardHeight, keyboardScrollExtraOffset]);
67
+ ], [keyboardHeight]);
68
68
  const containerStyle = useMemo(() => [
69
69
  styles.flex1,
70
70
  props.style
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/ZSContainer/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactNode, useEffect, useImperativeHandle, forwardRef, useRef, useState, useCallback, useMemo } from 'react';\r\nimport { ViewProps, StatusBar, StyleSheet, ScrollView, NativeSyntheticEvent, NativeScrollEvent, Keyboard, View, Platform } from 'react-native';\r\nimport { SafeAreaView } from 'react-native-safe-area-context';\r\nimport { useTheme } from '../../model/useThemeProvider';\r\n\r\nconst IS_IOS = Platform.OS === 'ios';\r\nconst KEYBOARD_ANIMATION_DELAY = 50;\r\nconst keyboardEvents = {\r\n showEvent: IS_IOS ? 'keyboardWillShow' as const : 'keyboardDidShow' as const,\r\n hideEvent: IS_IOS ? 'keyboardWillHide' as const : 'keyboardDidHide' as const,\r\n};\r\n\r\nexport type ZSContainerProps = ViewProps & {\r\n backgroundColor?: string;\r\n statusBarColor?: string;\r\n barStyle?: 'light-content' | 'dark-content';\r\n edges?: Array<'top' | 'right' | 'bottom' | 'left'>;\r\n scrollViewDisabled?: boolean;\r\n topComponent?: ReactNode;\r\n bottomComponent?: ReactNode;\r\n rightComponent?: ReactNode;\r\n showsVerticalScrollIndicator?: boolean;\r\n keyboardScrollExtraOffset?: number;\r\n translucent?: boolean;\r\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\r\n scrollEventThrottle?: number;\r\n scrollToFocusedInput?: boolean;\r\n};\r\n\r\nexport type ZSContainerRef = ScrollView;\r\n\r\nconst ZSContainer = forwardRef<ZSContainerRef, ZSContainerProps>(function ZSContainer(\r\n {\r\n backgroundColor,\r\n statusBarColor,\r\n barStyle,\r\n edges = ['top', 'bottom'],\r\n scrollViewDisabled = false,\r\n topComponent,\r\n bottomComponent,\r\n rightComponent,\r\n showsVerticalScrollIndicator = true,\r\n keyboardScrollExtraOffset = 30,\r\n translucent,\r\n scrollEventThrottle = 16,\r\n scrollToFocusedInput = true,\r\n ...props\r\n },\r\n forwardedRef\r\n) {\r\n const { palette, dimensions: { height: windowHeight } } = useTheme();\r\n const positionRef = useRef<number | null>(0);\r\n const scrollViewRef = useRef<ScrollView>(null);\r\n const lastTouchY = useRef<number | null>(0);\r\n const [keyboardHeight, setKeyboardHeight] = useState<number | null>(0);\r\n\r\n useImperativeHandle(forwardedRef, () => scrollViewRef.current as ScrollView, []);\r\n\r\n const handleKeyboardShow = useCallback((e: any) => {\r\n setKeyboardHeight(e.endCoordinates.height);\r\n \r\n if (scrollViewRef.current && scrollToFocusedInput) {\r\n const keyboardHeight = e.endCoordinates.height;\r\n const safeAreaBottom = 0;\r\n const availableScreenHeight = windowHeight - keyboardHeight - safeAreaBottom;\r\n const currentScrollPosition = positionRef.current || 0;\r\n const touchPosition = lastTouchY.current || 0;\r\n\r\n // 현재 터치 위치와 스크롤 위치를 기반으로 새로운 스크롤 위치 계산\r\n const scrollOffset = touchPosition - availableScreenHeight + keyboardScrollExtraOffset;\r\n\r\n setTimeout(() => {\r\n scrollViewRef.current?.scrollTo({\r\n y: currentScrollPosition + scrollOffset,\r\n animated: true,\r\n });\r\n }, KEYBOARD_ANIMATION_DELAY);\r\n }\r\n }, [windowHeight, keyboardScrollExtraOffset, scrollToFocusedInput]);\r\n\r\n // 키보드 숨김 핸들러를 메모이제이션하여 성능 최적화\r\n const handleKeyboardHide = useCallback(() => {\r\n setKeyboardHeight(0);\r\n }, []);\r\n\r\n useEffect(() => {\r\n const keyboardShowSubscription = Keyboard.addListener(keyboardEvents.showEvent, handleKeyboardShow);\r\n const keyboardHideSubscription = Keyboard.addListener(keyboardEvents.hideEvent, handleKeyboardHide);\r\n\r\n return () => {\r\n positionRef.current = null;\r\n lastTouchY.current = null;\r\n keyboardShowSubscription.remove();\r\n keyboardHideSubscription.remove();\r\n };\r\n }, [keyboardEvents.showEvent, keyboardEvents.hideEvent, handleKeyboardShow, handleKeyboardHide]);\r\n\r\n const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\r\n if (props.onScroll) props.onScroll(event);\r\n positionRef.current = event.nativeEvent.contentOffset.y;\r\n }, [props.onScroll]);\r\n\r\n const handleTouch = useCallback((evt: any) => {\r\n lastTouchY.current = evt.nativeEvent.pageY;\r\n }, []);\r\n\r\n const safeAreaStyle = useMemo(() => [\r\n { backgroundColor: backgroundColor || palette.background.base }, \r\n styles.flex1\r\n ], [backgroundColor, palette.background.base]);\r\n\r\n const scrollContentStyle = useMemo(() => [\r\n styles.scrollContainerStyle, \r\n { \r\n paddingBottom: keyboardHeight ? (IS_IOS ? keyboardHeight : keyboardScrollExtraOffset) : 0 \r\n }\r\n ], [keyboardHeight, keyboardScrollExtraOffset]);\r\n\r\n const containerStyle = useMemo(() => [\r\n styles.flex1, \r\n props.style\r\n ], [props.style]);\r\n\r\n const shouldShowStatusBar = useMemo(() => \r\n Boolean(barStyle || statusBarColor || translucent), \r\n [barStyle, statusBarColor, translucent]\r\n );\r\n\r\n return (\r\n <SafeAreaView\r\n style={safeAreaStyle}\r\n edges={edges}\r\n >\r\n <View style={styles.flex1}>\r\n {topComponent}\r\n {\r\n scrollViewDisabled ? (\r\n <View style={styles.flex1}>\r\n {props.children}\r\n </View>\r\n ) : (\r\n <ScrollView\r\n ref={scrollViewRef}\r\n style={styles.flex1}\r\n contentContainerStyle={scrollContentStyle}\r\n bounces={false}\r\n overScrollMode=\"never\"\r\n showsVerticalScrollIndicator={showsVerticalScrollIndicator}\r\n keyboardShouldPersistTaps=\"handled\"\r\n automaticallyAdjustKeyboardInsets={false}\r\n onScroll={handleScroll}\r\n onTouchStart={handleTouch}\r\n scrollEventThrottle={scrollEventThrottle}\r\n >\r\n <View style={containerStyle}>\r\n {props.children}\r\n </View>\r\n </ScrollView>\r\n )\r\n }\r\n {bottomComponent}\r\n </View>\r\n\r\n {shouldShowStatusBar && (\r\n <StatusBar\r\n barStyle={barStyle}\r\n backgroundColor={statusBarColor || palette.background.base}\r\n translucent={translucent}\r\n />\r\n )}\r\n </SafeAreaView>\r\n );\r\n});\r\n\r\nexport const styles = StyleSheet.create({\r\n flex1: { flex: 1, width: '100%' },\r\n scrollContainerStyle: { flexGrow: 1, alignItems: 'center', width: '100%' },\r\n});\r\n\r\nconst arePropsEqual = (\r\n prevProps: ZSContainerProps, \r\n nextProps: ZSContainerProps\r\n): boolean => {\r\n return (\r\n prevProps.backgroundColor === nextProps.backgroundColor &&\r\n prevProps.statusBarColor === nextProps.statusBarColor &&\r\n prevProps.barStyle === nextProps.barStyle &&\r\n prevProps.scrollViewDisabled === nextProps.scrollViewDisabled &&\r\n prevProps.showsVerticalScrollIndicator === nextProps.showsVerticalScrollIndicator &&\r\n prevProps.keyboardScrollExtraOffset === nextProps.keyboardScrollExtraOffset &&\r\n prevProps.translucent === nextProps.translucent &&\r\n prevProps.scrollEventThrottle === nextProps.scrollEventThrottle &&\r\n prevProps.scrollToFocusedInput === nextProps.scrollToFocusedInput &&\r\n prevProps.onScroll === nextProps.onScroll &&\r\n prevProps.style === nextProps.style &&\r\n prevProps.children === nextProps.children &&\r\n prevProps.topComponent === nextProps.topComponent &&\r\n prevProps.bottomComponent === nextProps.bottomComponent &&\r\n prevProps.rightComponent === nextProps.rightComponent &&\r\n // edges 배열 비교\r\n JSON.stringify(prevProps.edges) === JSON.stringify(nextProps.edges)\r\n );\r\n};\r\n\r\nexport default React.memo(ZSContainer, arePropsEqual);\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/ZSContainer/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactNode, useEffect, useImperativeHandle, forwardRef, useRef, useState, useCallback, useMemo } from 'react';\r\nimport { ViewProps, StatusBar, StyleSheet, ScrollView, NativeSyntheticEvent, NativeScrollEvent, Keyboard, View, Platform } from 'react-native';\r\nimport { SafeAreaView } from 'react-native-safe-area-context';\r\nimport { useTheme } from '../../model/useThemeProvider';\r\n\r\nconst IS_IOS = Platform.OS === 'ios';\r\nconst KEYBOARD_ANIMATION_DELAY = 50;\r\nconst keyboardEvents = {\r\n showEvent: IS_IOS ? 'keyboardWillShow' as const : 'keyboardDidShow' as const,\r\n hideEvent: IS_IOS ? 'keyboardWillHide' as const : 'keyboardDidHide' as const,\r\n};\r\n\r\nexport type ZSContainerProps = ViewProps & {\r\n backgroundColor?: string;\r\n statusBarColor?: string;\r\n barStyle?: 'light-content' | 'dark-content';\r\n edges?: Array<'top' | 'right' | 'bottom' | 'left'>;\r\n scrollViewDisabled?: boolean;\r\n topComponent?: ReactNode;\r\n bottomComponent?: ReactNode;\r\n rightComponent?: ReactNode;\r\n showsVerticalScrollIndicator?: boolean;\r\n keyboardScrollExtraOffset?: number;\r\n translucent?: boolean;\r\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\r\n scrollEventThrottle?: number;\r\n scrollToFocusedInput?: boolean;\r\n};\r\n\r\nexport type ZSContainerRef = ScrollView;\r\n\r\nconst ZSContainer = forwardRef<ZSContainerRef, ZSContainerProps>(function ZSContainer(\r\n {\r\n backgroundColor,\r\n statusBarColor,\r\n barStyle,\r\n edges = ['top', 'bottom'],\r\n scrollViewDisabled = false,\r\n topComponent,\r\n bottomComponent,\r\n rightComponent,\r\n showsVerticalScrollIndicator = true,\r\n keyboardScrollExtraOffset = 30,\r\n translucent,\r\n scrollEventThrottle = 16,\r\n scrollToFocusedInput = true,\r\n ...props\r\n },\r\n forwardedRef\r\n) {\r\n const { palette, dimensions: { height: windowHeight } } = useTheme();\r\n const positionRef = useRef<number | null>(0);\r\n const scrollViewRef = useRef<ScrollView>(null);\r\n const lastTouchY = useRef<number | null>(0);\r\n const [keyboardHeight, setKeyboardHeight] = useState<number | null>(0);\r\n\r\n useImperativeHandle(forwardedRef, () => scrollViewRef.current as ScrollView, []);\r\n\r\n const handleKeyboardShow = useCallback((e: any) => {\r\n setKeyboardHeight(e.endCoordinates.height);\r\n \r\n if (scrollViewRef.current && scrollToFocusedInput) {\r\n const keyboardHeight = e.endCoordinates.height;\r\n const safeAreaBottom = 0;\r\n const availableScreenHeight = windowHeight - keyboardHeight - safeAreaBottom;\r\n const currentScrollPosition = positionRef.current || 0;\r\n const touchPosition = lastTouchY.current || 0;\r\n\r\n // 현재 터치 위치와 스크롤 위치를 기반으로 새로운 스크롤 위치 계산\r\n const scrollOffset = touchPosition - availableScreenHeight + keyboardScrollExtraOffset;\r\n\r\n setTimeout(() => {\r\n scrollViewRef.current?.scrollTo({\r\n y: currentScrollPosition + scrollOffset,\r\n animated: true,\r\n });\r\n }, KEYBOARD_ANIMATION_DELAY);\r\n }\r\n }, [windowHeight, keyboardScrollExtraOffset, scrollToFocusedInput]);\r\n\r\n // 키보드 숨김 핸들러를 메모이제이션하여 성능 최적화\r\n const handleKeyboardHide = useCallback(() => {\r\n setKeyboardHeight(0);\r\n }, []);\r\n\r\n useEffect(() => {\r\n const keyboardShowSubscription = Keyboard.addListener(keyboardEvents.showEvent, handleKeyboardShow);\r\n const keyboardHideSubscription = Keyboard.addListener(keyboardEvents.hideEvent, handleKeyboardHide);\r\n\r\n return () => {\r\n positionRef.current = null;\r\n lastTouchY.current = null;\r\n keyboardShowSubscription.remove();\r\n keyboardHideSubscription.remove();\r\n };\r\n }, [keyboardEvents.showEvent, keyboardEvents.hideEvent, handleKeyboardShow, handleKeyboardHide]);\r\n\r\n const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\r\n if (props.onScroll) props.onScroll(event);\r\n positionRef.current = event.nativeEvent.contentOffset.y;\r\n }, [props.onScroll]);\r\n\r\n const handleTouch = useCallback((evt: any) => {\r\n lastTouchY.current = evt.nativeEvent.pageY;\r\n }, []);\r\n\r\n const safeAreaStyle = useMemo(() => [\r\n { backgroundColor: backgroundColor || palette.background.base }, \r\n styles.flex1\r\n ], [backgroundColor, palette.background.base]);\r\n\r\n const scrollContentStyle = useMemo(() => [\r\n styles.scrollContainerStyle, \r\n { \r\n paddingBottom: keyboardHeight ? (IS_IOS ? keyboardHeight : 0) : 0 \r\n }\r\n ], [keyboardHeight]);\r\n\r\n const containerStyle = useMemo(() => [\r\n styles.flex1, \r\n props.style\r\n ], [props.style]);\r\n\r\n const shouldShowStatusBar = useMemo(() => \r\n Boolean(barStyle || statusBarColor || translucent), \r\n [barStyle, statusBarColor, translucent]\r\n );\r\n\r\n return (\r\n <SafeAreaView\r\n style={safeAreaStyle}\r\n edges={edges}\r\n >\r\n <View style={styles.flex1}>\r\n {topComponent}\r\n {\r\n scrollViewDisabled ? (\r\n <View style={styles.flex1}>\r\n {props.children}\r\n </View>\r\n ) : (\r\n <ScrollView\r\n ref={scrollViewRef}\r\n style={styles.flex1}\r\n contentContainerStyle={scrollContentStyle}\r\n bounces={false}\r\n overScrollMode=\"never\"\r\n showsVerticalScrollIndicator={showsVerticalScrollIndicator}\r\n keyboardShouldPersistTaps=\"handled\"\r\n automaticallyAdjustKeyboardInsets={false}\r\n onScroll={handleScroll}\r\n onTouchStart={handleTouch}\r\n scrollEventThrottle={scrollEventThrottle}\r\n >\r\n <View style={containerStyle}>\r\n {props.children}\r\n </View>\r\n </ScrollView>\r\n )\r\n }\r\n {bottomComponent}\r\n </View>\r\n\r\n {shouldShowStatusBar && (\r\n <StatusBar\r\n barStyle={barStyle}\r\n backgroundColor={statusBarColor || palette.background.base}\r\n translucent={translucent}\r\n />\r\n )}\r\n </SafeAreaView>\r\n );\r\n});\r\n\r\nexport const styles = StyleSheet.create({\r\n flex1: { flex: 1, width: '100%' },\r\n scrollContainerStyle: { flexGrow: 1, alignItems: 'center', width: '100%' },\r\n});\r\n\r\nconst arePropsEqual = (\r\n prevProps: ZSContainerProps, \r\n nextProps: ZSContainerProps\r\n): boolean => {\r\n return (\r\n prevProps.backgroundColor === nextProps.backgroundColor &&\r\n prevProps.statusBarColor === nextProps.statusBarColor &&\r\n prevProps.barStyle === nextProps.barStyle &&\r\n prevProps.scrollViewDisabled === nextProps.scrollViewDisabled &&\r\n prevProps.showsVerticalScrollIndicator === nextProps.showsVerticalScrollIndicator &&\r\n prevProps.keyboardScrollExtraOffset === nextProps.keyboardScrollExtraOffset &&\r\n prevProps.translucent === nextProps.translucent &&\r\n prevProps.scrollEventThrottle === nextProps.scrollEventThrottle &&\r\n prevProps.scrollToFocusedInput === nextProps.scrollToFocusedInput &&\r\n prevProps.onScroll === nextProps.onScroll &&\r\n prevProps.style === nextProps.style &&\r\n prevProps.children === nextProps.children &&\r\n prevProps.topComponent === nextProps.topComponent &&\r\n prevProps.bottomComponent === nextProps.bottomComponent &&\r\n prevProps.rightComponent === nextProps.rightComponent &&\r\n // edges 배열 비교\r\n JSON.stringify(prevProps.edges) === JSON.stringify(nextProps.edges)\r\n );\r\n};\r\n\r\nexport default React.memo(ZSContainer, arePropsEqual);\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0610studio/zs-ui",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "private": false,
5
5
  "description": "EXPO ZS-UI",
6
6
  "type": "commonjs",