@0610studio/zs-ui 0.0.1

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.
Files changed (250) hide show
  1. package/.eslintrc.js +5 -0
  2. package/README.md +3 -0
  3. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  4. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  5. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  6. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  7. package/android/.gradle/8.9/gc.properties +0 -0
  8. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  9. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  10. package/android/.gradle/vcs-1/gc.properties +0 -0
  11. package/android/build.gradle +43 -0
  12. package/android/src/main/AndroidManifest.xml +2 -0
  13. package/android/src/main/java/kr/co/studio0610/zsui/ZsUiModule.kt +47 -0
  14. package/android/src/main/java/kr/co/studio0610/zsui/ZsUiView.kt +7 -0
  15. package/build/ZsUi.types.d.ts +7 -0
  16. package/build/ZsUi.types.d.ts.map +1 -0
  17. package/build/ZsUi.types.js +2 -0
  18. package/build/ZsUi.types.js.map +1 -0
  19. package/build/ZsUiModule.d.ts +3 -0
  20. package/build/ZsUiModule.d.ts.map +1 -0
  21. package/build/ZsUiModule.js +5 -0
  22. package/build/ZsUiModule.js.map +1 -0
  23. package/build/ZsUiModule.web.d.ts +7 -0
  24. package/build/ZsUiModule.web.d.ts.map +1 -0
  25. package/build/ZsUiModule.web.js +12 -0
  26. package/build/ZsUiModule.web.js.map +1 -0
  27. package/build/ZsUiView.d.ts +4 -0
  28. package/build/ZsUiView.d.ts.map +1 -0
  29. package/build/ZsUiView.js +7 -0
  30. package/build/ZsUiView.js.map +1 -0
  31. package/build/ZsUiView.web.d.ts +4 -0
  32. package/build/ZsUiView.web.d.ts.map +1 -0
  33. package/build/ZsUiView.web.js +7 -0
  34. package/build/ZsUiView.web.js.map +1 -0
  35. package/build/assets/SvgCheck.d.ts +7 -0
  36. package/build/assets/SvgCheck.d.ts.map +1 -0
  37. package/build/assets/SvgCheck.js +8 -0
  38. package/build/assets/SvgCheck.js.map +1 -0
  39. package/build/assets/SvgX.d.ts +6 -0
  40. package/build/assets/SvgX.d.ts.map +1 -0
  41. package/build/assets/SvgX.js +14 -0
  42. package/build/assets/SvgX.js.map +1 -0
  43. package/build/index.d.ts +5 -0
  44. package/build/index.d.ts.map +1 -0
  45. package/build/index.js +10 -0
  46. package/build/index.js.map +1 -0
  47. package/build/model/types.d.ts +84 -0
  48. package/build/model/types.d.ts.map +1 -0
  49. package/build/model/types.js +11 -0
  50. package/build/model/types.js.map +1 -0
  51. package/build/model/useNotify.d.ts +5 -0
  52. package/build/model/useNotify.d.ts.map +1 -0
  53. package/build/model/useNotify.js +11 -0
  54. package/build/model/useNotify.js.map +1 -0
  55. package/build/model/useNotifyProvider.d.ts +3 -0
  56. package/build/model/useNotifyProvider.d.ts.map +1 -0
  57. package/build/model/useNotifyProvider.js +165 -0
  58. package/build/model/useNotifyProvider.js.map +1 -0
  59. package/build/model/useThemeProvider.d.ts +19 -0
  60. package/build/model/useThemeProvider.d.ts.map +1 -0
  61. package/build/model/useThemeProvider.js +73 -0
  62. package/build/model/useThemeProvider.js.map +1 -0
  63. package/build/model/utils.d.ts +12 -0
  64. package/build/model/utils.d.ts.map +1 -0
  65. package/build/model/utils.js +26 -0
  66. package/build/model/utils.js.map +1 -0
  67. package/build/notify/AlertNotify/index.d.ts +5 -0
  68. package/build/notify/AlertNotify/index.d.ts.map +1 -0
  69. package/build/notify/AlertNotify/index.js +109 -0
  70. package/build/notify/AlertNotify/index.js.map +1 -0
  71. package/build/notify/BottomSheetNotify/index.d.ts +19 -0
  72. package/build/notify/BottomSheetNotify/index.d.ts.map +1 -0
  73. package/build/notify/BottomSheetNotify/index.js +90 -0
  74. package/build/notify/BottomSheetNotify/index.js.map +1 -0
  75. package/build/notify/BottomSheetNotify/model/useBottomSheetNotify.d.ts +43 -0
  76. package/build/notify/BottomSheetNotify/model/useBottomSheetNotify.d.ts.map +1 -0
  77. package/build/notify/BottomSheetNotify/model/useBottomSheetNotify.js +222 -0
  78. package/build/notify/BottomSheetNotify/model/useBottomSheetNotify.js.map +1 -0
  79. package/build/notify/BottomSheetNotify/types/index.d.ts +4 -0
  80. package/build/notify/BottomSheetNotify/types/index.d.ts.map +1 -0
  81. package/build/notify/BottomSheetNotify/types/index.js +2 -0
  82. package/build/notify/BottomSheetNotify/types/index.js.map +1 -0
  83. package/build/notify/BottomSheetNotify/ui/BSTextInput/index.d.ts +4 -0
  84. package/build/notify/BottomSheetNotify/ui/BSTextInput/index.d.ts.map +1 -0
  85. package/build/notify/BottomSheetNotify/ui/BSTextInput/index.js +14 -0
  86. package/build/notify/BottomSheetNotify/ui/BSTextInput/index.js.map +1 -0
  87. package/build/notify/BottomSheetNotify/ui/ContentsComponent/index.d.ts +19 -0
  88. package/build/notify/BottomSheetNotify/ui/ContentsComponent/index.d.ts.map +1 -0
  89. package/build/notify/BottomSheetNotify/ui/ContentsComponent/index.js +33 -0
  90. package/build/notify/BottomSheetNotify/ui/ContentsComponent/index.js.map +1 -0
  91. package/build/notify/LoadingNotify/index.d.ts +6 -0
  92. package/build/notify/LoadingNotify/index.d.ts.map +1 -0
  93. package/build/notify/LoadingNotify/index.js +28 -0
  94. package/build/notify/LoadingNotify/index.js.map +1 -0
  95. package/build/notify/PopOver/PopOverButton.d.ts +11 -0
  96. package/build/notify/PopOver/PopOverButton.d.ts.map +1 -0
  97. package/build/notify/PopOver/PopOverButton.js +31 -0
  98. package/build/notify/PopOver/PopOverButton.js.map +1 -0
  99. package/build/notify/PopOver/PopOverMenu.d.ts +4 -0
  100. package/build/notify/PopOver/PopOverMenu.d.ts.map +1 -0
  101. package/build/notify/PopOver/PopOverMenu.js +69 -0
  102. package/build/notify/PopOver/PopOverMenu.js.map +1 -0
  103. package/build/notify/SnackbarNotify/index.d.ts +7 -0
  104. package/build/notify/SnackbarNotify/index.d.ts.map +1 -0
  105. package/build/notify/SnackbarNotify/index.js +24 -0
  106. package/build/notify/SnackbarNotify/index.js.map +1 -0
  107. package/build/notify/SnackbarNotify/ui/SnackbarItem.d.ts +9 -0
  108. package/build/notify/SnackbarNotify/ui/SnackbarItem.d.ts.map +1 -0
  109. package/build/notify/SnackbarNotify/ui/SnackbarItem.js +72 -0
  110. package/build/notify/SnackbarNotify/ui/SnackbarItem.js.map +1 -0
  111. package/build/notify/index.d.ts +11 -0
  112. package/build/notify/index.d.ts.map +1 -0
  113. package/build/notify/index.js +11 -0
  114. package/build/notify/index.js.map +1 -0
  115. package/build/notify/ui/ModalBackground.d.ts +9 -0
  116. package/build/notify/ui/ModalBackground.d.ts.map +1 -0
  117. package/build/notify/ui/ModalBackground.js +27 -0
  118. package/build/notify/ui/ModalBackground.js.map +1 -0
  119. package/build/theme/index.d.ts +4 -0
  120. package/build/theme/index.d.ts.map +1 -0
  121. package/build/theme/index.js +4 -0
  122. package/build/theme/index.js.map +1 -0
  123. package/build/theme/palette.d.ts +62 -0
  124. package/build/theme/palette.d.ts.map +1 -0
  125. package/build/theme/palette.js +353 -0
  126. package/build/theme/palette.js.map +1 -0
  127. package/build/theme/types.d.ts +101 -0
  128. package/build/theme/types.d.ts.map +1 -0
  129. package/build/theme/types.js +5 -0
  130. package/build/theme/types.js.map +1 -0
  131. package/build/theme/typography.d.ts +5 -0
  132. package/build/theme/typography.d.ts.map +1 -0
  133. package/build/theme/typography.js +198 -0
  134. package/build/theme/typography.js.map +1 -0
  135. package/build/ui/ThrottleButton/index.d.ts +15 -0
  136. package/build/ui/ThrottleButton/index.d.ts.map +1 -0
  137. package/build/ui/ThrottleButton/index.js +74 -0
  138. package/build/ui/ThrottleButton/index.js.map +1 -0
  139. package/build/ui/ZSBottomButton/index.d.ts +16 -0
  140. package/build/ui/ZSBottomButton/index.d.ts.map +1 -0
  141. package/build/ui/ZSBottomButton/index.js +89 -0
  142. package/build/ui/ZSBottomButton/index.js.map +1 -0
  143. package/build/ui/ZSContainer/index.d.ts +19 -0
  144. package/build/ui/ZSContainer/index.d.ts.map +1 -0
  145. package/build/ui/ZSContainer/index.js +37 -0
  146. package/build/ui/ZSContainer/index.js.map +1 -0
  147. package/build/ui/ZSPressable/index.d.ts +17 -0
  148. package/build/ui/ZSPressable/index.d.ts.map +1 -0
  149. package/build/ui/ZSPressable/index.js +35 -0
  150. package/build/ui/ZSPressable/index.js.map +1 -0
  151. package/build/ui/ZSRadioGroup/index.d.ts +18 -0
  152. package/build/ui/ZSRadioGroup/index.d.ts.map +1 -0
  153. package/build/ui/ZSRadioGroup/index.js +82 -0
  154. package/build/ui/ZSRadioGroup/index.js.map +1 -0
  155. package/build/ui/ZSText/index.d.ts +11 -0
  156. package/build/ui/ZSText/index.d.ts.map +1 -0
  157. package/build/ui/ZSText/index.js +10 -0
  158. package/build/ui/ZSText/index.js.map +1 -0
  159. package/build/ui/ZSTextField/index.d.ts +31 -0
  160. package/build/ui/ZSTextField/index.d.ts.map +1 -0
  161. package/build/ui/ZSTextField/index.js +102 -0
  162. package/build/ui/ZSTextField/index.js.map +1 -0
  163. package/build/ui/ZSTextField/ui/ButtonClose.d.ts +6 -0
  164. package/build/ui/ZSTextField/ui/ButtonClose.d.ts.map +1 -0
  165. package/build/ui/ZSTextField/ui/ButtonClose.js +9 -0
  166. package/build/ui/ZSTextField/ui/ButtonClose.js.map +1 -0
  167. package/build/ui/ZSTextField/ui/ErrorComponent.d.ts +7 -0
  168. package/build/ui/ZSTextField/ui/ErrorComponent.d.ts.map +1 -0
  169. package/build/ui/ZSTextField/ui/ErrorComponent.js +16 -0
  170. package/build/ui/ZSTextField/ui/ErrorComponent.js.map +1 -0
  171. package/build/ui/ZSView/index.d.ts +8 -0
  172. package/build/ui/ZSView/index.d.ts.map +1 -0
  173. package/build/ui/ZSView/index.js +17 -0
  174. package/build/ui/ZSView/index.js.map +1 -0
  175. package/build/ui/atoms/AnimatedWrapper.d.ts +12 -0
  176. package/build/ui/atoms/AnimatedWrapper.d.ts.map +1 -0
  177. package/build/ui/atoms/AnimatedWrapper.js +61 -0
  178. package/build/ui/atoms/AnimatedWrapper.js.map +1 -0
  179. package/build/ui/atoms/ScrollViewAtom.d.ts +5 -0
  180. package/build/ui/atoms/ScrollViewAtom.d.ts.map +1 -0
  181. package/build/ui/atoms/ScrollViewAtom.js +10 -0
  182. package/build/ui/atoms/ScrollViewAtom.js.map +1 -0
  183. package/build/ui/atoms/TextAtom.d.ts +6 -0
  184. package/build/ui/atoms/TextAtom.d.ts.map +1 -0
  185. package/build/ui/atoms/TextAtom.js +9 -0
  186. package/build/ui/atoms/TextAtom.js.map +1 -0
  187. package/build/ui/atoms/ViewAtom.d.ts +6 -0
  188. package/build/ui/atoms/ViewAtom.d.ts.map +1 -0
  189. package/build/ui/atoms/ViewAtom.js +9 -0
  190. package/build/ui/atoms/ViewAtom.js.map +1 -0
  191. package/build/ui/index.d.ts +14 -0
  192. package/build/ui/index.d.ts.map +1 -0
  193. package/build/ui/index.js +14 -0
  194. package/build/ui/index.js.map +1 -0
  195. package/build/ui/types.d.ts +14 -0
  196. package/build/ui/types.d.ts.map +1 -0
  197. package/build/ui/types.js +2 -0
  198. package/build/ui/types.js.map +1 -0
  199. package/expo-module.config.json +9 -0
  200. package/ios/ZsUi.podspec +27 -0
  201. package/ios/ZsUiModule.swift +44 -0
  202. package/ios/ZsUiView.swift +7 -0
  203. package/package.json +54 -0
  204. package/src/ZsUi.types.ts +7 -0
  205. package/src/ZsUiModule.ts +5 -0
  206. package/src/ZsUiModule.web.ts +13 -0
  207. package/src/ZsUiView.tsx +11 -0
  208. package/src/ZsUiView.web.tsx +11 -0
  209. package/src/assets/SvgCheck.tsx +16 -0
  210. package/src/assets/SvgX.tsx +22 -0
  211. package/src/index.ts +52 -0
  212. package/src/model/types.ts +102 -0
  213. package/src/model/useNotify.ts +14 -0
  214. package/src/model/useNotifyProvider.tsx +251 -0
  215. package/src/model/useThemeProvider.tsx +99 -0
  216. package/src/model/utils.ts +31 -0
  217. package/src/notify/AlertNotify/index.tsx +177 -0
  218. package/src/notify/BottomSheetNotify/index.tsx +177 -0
  219. package/src/notify/BottomSheetNotify/model/useBottomSheetNotify.tsx +270 -0
  220. package/src/notify/BottomSheetNotify/types/index.ts +3 -0
  221. package/src/notify/BottomSheetNotify/ui/BSTextInput/index.tsx +28 -0
  222. package/src/notify/BottomSheetNotify/ui/ContentsComponent/index.tsx +76 -0
  223. package/src/notify/LoadingNotify/index.tsx +46 -0
  224. package/src/notify/PopOver/PopOverButton.tsx +56 -0
  225. package/src/notify/PopOver/PopOverMenu.tsx +95 -0
  226. package/src/notify/SnackbarNotify/index.tsx +43 -0
  227. package/src/notify/SnackbarNotify/ui/SnackbarItem.tsx +103 -0
  228. package/src/notify/index.ts +21 -0
  229. package/src/notify/ui/ModalBackground.tsx +46 -0
  230. package/src/theme/index.ts +3 -0
  231. package/src/theme/palette.ts +374 -0
  232. package/src/theme/types.ts +150 -0
  233. package/src/theme/typography.ts +199 -0
  234. package/src/ui/ThrottleButton/index.tsx +119 -0
  235. package/src/ui/ZSBottomButton/index.tsx +151 -0
  236. package/src/ui/ZSContainer/index.tsx +92 -0
  237. package/src/ui/ZSPressable/index.tsx +82 -0
  238. package/src/ui/ZSRadioGroup/index.tsx +141 -0
  239. package/src/ui/ZSText/index.tsx +22 -0
  240. package/src/ui/ZSTextField/index.tsx +200 -0
  241. package/src/ui/ZSTextField/ui/ButtonClose.tsx +20 -0
  242. package/src/ui/ZSTextField/ui/ErrorComponent.tsx +25 -0
  243. package/src/ui/ZSView/index.tsx +30 -0
  244. package/src/ui/atoms/AnimatedWrapper.tsx +89 -0
  245. package/src/ui/atoms/ScrollViewAtom.tsx +17 -0
  246. package/src/ui/atoms/TextAtom.tsx +15 -0
  247. package/src/ui/atoms/ViewAtom.tsx +15 -0
  248. package/src/ui/index.ts +27 -0
  249. package/src/ui/types.ts +12 -0
  250. package/tsconfig.json +9 -0
@@ -0,0 +1,95 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ import { BackHandler, Dimensions, LayoutChangeEvent, Pressable } from "react-native";
3
+ import Animated, { FadeInUp, FadeOutUp } from "react-native-reanimated";
4
+ import { useNotify } from "../../model/useNotify";
5
+ import ModalBackground from "../ui/ModalBackground";
6
+ import { PopOverMenuProps } from "../../model/types";
7
+
8
+ // 화면 높이 가져오기
9
+ const WINDOW_HEIGHT = Dimensions.get('window').height;
10
+
11
+ function PopOverMenu({
12
+ px,
13
+ py,
14
+ component
15
+ }: PopOverMenuProps): JSX.Element | null {
16
+ const [isContentVisible, setIsContentVisible] = useState<boolean>(false);
17
+ const [contentWidth, setContentWidth] = useState<number>(0);
18
+ const [contentHeight, setContentHeight] = useState<number>(0);
19
+ const { popOverVisible, setPopOverVisible } = useNotify();
20
+ const timerRef = useRef<number | null>(null);
21
+
22
+ // 뒤로가기 버튼 처리 핸들러
23
+ const handleBackPress = useCallback((): boolean => {
24
+ if (popOverVisible) {
25
+ setIsContentVisible(false);
26
+ setPopOverVisible(false);
27
+ return true; // 뒤로가기 액션을 막음
28
+ }
29
+ return false; // 기본 동작 허용
30
+ }, [popOverVisible, setPopOverVisible]);
31
+
32
+ // 뒤로가기 이벤트 리스너 추가 및 제거
33
+ useEffect(() => {
34
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', handleBackPress);
35
+
36
+ return () => backHandler.remove();
37
+ }, [handleBackPress]);
38
+
39
+ // 레이아웃 크기 계산
40
+ const handleLayout = useCallback((event: LayoutChangeEvent): void => {
41
+ setContentWidth(event.nativeEvent.layout.width || 0);
42
+ setContentHeight(event.nativeEvent.layout.height || 0);
43
+ }, []);
44
+
45
+ // PopOver가 보일 때 콘텐츠를 딜레이 후 보여줌
46
+ useEffect(() => {
47
+ if (popOverVisible) {
48
+ if (timerRef.current) {
49
+ clearTimeout(timerRef.current);
50
+ }
51
+
52
+ timerRef.current = setTimeout(() => {
53
+ setIsContentVisible(true);
54
+ }, 200);
55
+ }
56
+
57
+ return () => {
58
+ if (timerRef.current) {
59
+ clearTimeout(timerRef.current);
60
+ timerRef.current = null;
61
+ }
62
+ };
63
+ }, [popOverVisible]);
64
+
65
+ // 화면 크기에 따른 위치 조정
66
+ const isVerticalOverflow = WINDOW_HEIGHT < (py + contentHeight);
67
+ const isHorizontalOverflow = Dimensions.get('window').width > (px + contentWidth);
68
+
69
+ if (!popOverVisible) return null;
70
+
71
+ return (
72
+ <ModalBackground isCenter={false} onPress={() => setPopOverVisible(false)}>
73
+ {isContentVisible && (
74
+ <Animated.View
75
+ entering={FadeInUp}
76
+ exiting={FadeOutUp}
77
+ >
78
+ {/* PopOver의 위치를 세밀하게 조정 */}
79
+ <Pressable
80
+ style={{
81
+ position: 'absolute',
82
+ top: py - (isVerticalOverflow ? (contentHeight + 10) : 0),
83
+ left: px - contentWidth + (isHorizontalOverflow ? contentWidth : 0),
84
+ }}
85
+ onLayout={handleLayout}
86
+ >
87
+ {component}
88
+ </Pressable>
89
+ </Animated.View>
90
+ )}
91
+ </ModalBackground>
92
+ );
93
+ }
94
+
95
+ export default PopOverMenu;
@@ -0,0 +1,43 @@
1
+ import React, { ReactNode } from "react";
2
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
3
+ import { StyleSheet, View } from "react-native";
4
+ import { CustomSnackbarProps } from "../../model/types";
5
+ import SnackbarItem from "./ui/SnackbarItem";
6
+ import { useNotify } from "../../model/useNotify";
7
+
8
+ const SnackbarNotify = ({
9
+ customSnackbar
10
+ }: {
11
+ customSnackbar?: (props: CustomSnackbarProps) => ReactNode
12
+ }) => {
13
+ const { top } = useSafeAreaInsets();
14
+ const { snackItemStack, hideSnackBar } = useNotify();
15
+
16
+ return snackItemStack ? (
17
+ <View style={[styles.container, { paddingTop: top }]}>
18
+ {
19
+ snackItemStack.map((snackItem, index) => {
20
+ return (
21
+ <SnackbarItem
22
+ key={index}
23
+ customSnackbar={customSnackbar}
24
+ snackItem={snackItem}
25
+ hideSnackBar={hideSnackBar}
26
+ />
27
+ );
28
+ })
29
+ }
30
+ </View>
31
+ ) : null;
32
+ };
33
+
34
+ const styles = StyleSheet.create({
35
+ container: {
36
+ zIndex: 9997,
37
+ width: '100%',
38
+ alignItems: 'center',
39
+ position: 'absolute',
40
+ },
41
+ });
42
+
43
+ export default SnackbarNotify;
@@ -0,0 +1,103 @@
1
+ import React, { ReactNode, useEffect, useCallback } from "react";
2
+ import { Platform, StyleSheet, TouchableOpacity } from "react-native";
3
+ import Animated, { FadeInUp, FadeOutUp } from "react-native-reanimated";
4
+ import { CustomSnackbarProps, SnackItem } from "../../../model/types";
5
+ import ViewAtom from "../../../ui/atoms/ViewAtom";
6
+ import { ZSText } from "../../../ui";
7
+ import { useTheme } from "../../../model/useThemeProvider";
8
+
9
+ const Snackbar = ({
10
+ customSnackbar,
11
+ snackItem,
12
+ hideSnackBar,
13
+ }: {
14
+ customSnackbar?: (props: CustomSnackbarProps) => ReactNode;
15
+ snackItem: SnackItem;
16
+ hideSnackBar: (index: number) => void;
17
+ }) => {
18
+ const { type, message, snackbarDuration } = snackItem;
19
+ const { palette } = useTheme();
20
+
21
+ const closeSnackbar = useCallback(() => {
22
+ hideSnackBar(snackItem.index);
23
+ }, [hideSnackBar, snackItem.index]);
24
+
25
+ useEffect(() => {
26
+ const closeTimeout = setTimeout(closeSnackbar, snackbarDuration);
27
+
28
+ return () => clearTimeout(closeTimeout);
29
+ }, [snackbarDuration, closeSnackbar]);
30
+
31
+ return (
32
+ <Animated.View
33
+ style={[styles.container, styles.aosShadow, styles.snackbarWrapper]}
34
+ entering={FadeInUp}
35
+ exiting={FadeOutUp}
36
+ >
37
+ <TouchableOpacity
38
+ style={[styles.container, styles.iosShadow, styles.touchable]}
39
+ activeOpacity={1}
40
+ onPress={closeSnackbar}
41
+ >
42
+ {customSnackbar ? (
43
+ customSnackbar({ snackType: type, snackMessage: message })
44
+ ) : (
45
+ <ViewAtom
46
+ style={[
47
+ styles.snackBar,
48
+ { backgroundColor: type === "error" ? palette.background.danger : palette.background.success },
49
+ ]}
50
+ >
51
+ <ViewAtom style={styles.messageContainer}>
52
+ <ZSText>{message}</ZSText>
53
+ </ViewAtom>
54
+ </ViewAtom>
55
+ )}
56
+ </TouchableOpacity>
57
+ </Animated.View>
58
+ );
59
+ };
60
+
61
+ const styles = StyleSheet.create({
62
+ container: {
63
+ borderRadius: 16,
64
+ backgroundColor: "white",
65
+ },
66
+ iosShadow: {
67
+ ...Platform.select({
68
+ ios: {
69
+ shadowColor: "rgb(50, 50, 50)",
70
+ shadowOpacity: 0.12,
71
+ shadowRadius: 5,
72
+ shadowOffset: { height: 3, width: 0 },
73
+ },
74
+ }),
75
+ },
76
+ aosShadow: {
77
+ ...Platform.select({
78
+ android: { elevation: 5 },
79
+ }),
80
+ },
81
+ snackbarWrapper: {
82
+ width: "94%",
83
+ marginTop: 10,
84
+ },
85
+ touchable: {
86
+ width: "100%",
87
+ },
88
+ snackBar: {
89
+ borderRadius: 16,
90
+ paddingHorizontal: 10,
91
+ paddingVertical: 18,
92
+ flexDirection: "row",
93
+ alignItems: "center",
94
+ width: "100%",
95
+ },
96
+ messageContainer: {
97
+ flex: 1,
98
+ flexDirection: "column",
99
+ marginLeft: 10,
100
+ },
101
+ });
102
+
103
+ export default Snackbar;
@@ -0,0 +1,21 @@
1
+ import AlertNotify from './AlertNotify';
2
+ import BottomSheetNotify from './BottomSheetNotify';
3
+ import SnackbarNotify from './SnackbarNotify';
4
+ import BSTextInput from './BottomSheetNotify/ui/BSTextInput';
5
+ import * as useNotifyProvider from '../model/useNotifyProvider';
6
+ import { useNotify } from '../model/useNotify';
7
+ import PopOverButton from './PopOver/PopOverButton';
8
+ import PopOverMenu from './PopOver/PopOverMenu';
9
+ import * as types from '../model/types';
10
+
11
+ export {
12
+ AlertNotify,
13
+ BottomSheetNotify,
14
+ SnackbarNotify,
15
+ useNotifyProvider,
16
+ useNotify,
17
+ BSTextInput,
18
+ PopOverButton,
19
+ PopOverMenu,
20
+ types,
21
+ }
@@ -0,0 +1,46 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Pressable, StyleSheet } from 'react-native';
3
+ import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
4
+ import { useTheme } from '../../model/useThemeProvider';
5
+
6
+ interface ModalBackgroundProps {
7
+ isCenter?: boolean;
8
+ children: React.ReactNode;
9
+ onPress?: () => void;
10
+ }
11
+
12
+ function ModalBackground({ isCenter = true, children, onPress }: ModalBackgroundProps) {
13
+ const { palette: { modalBgColor } } = useTheme();
14
+ const styles = useMemo(() => createStyles(modalBgColor), [modalBgColor]);
15
+
16
+ return (
17
+ <Animated.View
18
+ style={styles.modalBg}
19
+ entering={FadeIn.duration(50)}
20
+ exiting={FadeOut.duration(50)}
21
+ >
22
+ <Pressable
23
+ style={[styles.fullScreen, isCenter && { justifyContent: 'center', alignItems: 'center' }]}
24
+ onPress={onPress ?? (() => { })}
25
+ >
26
+ {children}
27
+ </Pressable>
28
+ </Animated.View>
29
+ );
30
+ }
31
+
32
+ // 스타일을 생성하는 함수, 모달 배경 색상 인자로 받음
33
+ const createStyles = (modalBgColor: string) =>
34
+ StyleSheet.create({
35
+ modalBg: {
36
+ zIndex: 9997,
37
+ backgroundColor: modalBgColor,
38
+ ...StyleSheet.absoluteFillObject,
39
+ },
40
+ // 화면 전체를 덮는 Pressable 스타일 추가
41
+ fullScreen: {
42
+ ...StyleSheet.absoluteFillObject,
43
+ },
44
+ });
45
+
46
+ export default ModalBackground;
@@ -0,0 +1,3 @@
1
+ export * from './palette';
2
+ export * from './types';
3
+ export * from './typography';
@@ -0,0 +1,374 @@
1
+ import { Theme } from "./types";
2
+
3
+ export const transparency = {
4
+ '0%': '00', // 완전 투명
5
+ '2%': '05',
6
+ '4%': '0A',
7
+ '6%': '0F',
8
+ '8%': '14',
9
+ '10%': '1A',
10
+ '12%': '1F',
11
+ '14%': '24',
12
+ '16%': '29',
13
+ '18%': '2E',
14
+ '20%': '33',
15
+ '22%': '38',
16
+ '24%': '3D',
17
+ '26%': '42',
18
+ '28%': '47',
19
+ '30%': '4D',
20
+ '32%': '52',
21
+ '34%': '57',
22
+ '36%': '5C',
23
+ '38%': '61',
24
+ '40%': '66',
25
+ '42%': '6B',
26
+ '44%': '70',
27
+ '46%': '75',
28
+ '48%': '7A',
29
+ '50%': '80',
30
+ '52%': '85',
31
+ '54%': '8A',
32
+ '56%': '8F',
33
+ '58%': '94',
34
+ '60%': '99',
35
+ '62%': '9E',
36
+ '64%': 'A3',
37
+ '66%': 'A8',
38
+ '68%': 'AD',
39
+ '70%': 'B3',
40
+ '72%': 'B8',
41
+ '74%': 'BD',
42
+ '76%': 'C2',
43
+ '78%': 'C7',
44
+ '80%': 'CC',
45
+ '82%': 'D1',
46
+ '84%': 'D6',
47
+ '86%': 'DB',
48
+ '88%': 'E0',
49
+ '90%': 'E6',
50
+ '92%': 'EB',
51
+ '94%': 'F0',
52
+ '96%': 'F5',
53
+ '98%': 'FA',
54
+ '100%': 'FF' // 완전 불투명
55
+ };
56
+
57
+ const MODAL_BG_COLOR = {
58
+ light: '#212B3688',
59
+ dark: '#00000088'
60
+ }
61
+
62
+ const SHADOW_COLORS = {
63
+ light: [
64
+ 'rgba(0, 0, 0, 0.18)',
65
+ 'rgba(0, 0, 0, 0.20)',
66
+ 'rgba(0, 0, 0, 0.22)',
67
+ 'rgba(0, 0, 0, 0.23)',
68
+ 'rgba(0, 0, 0, 0.25)',
69
+ 'rgba(0, 0, 0, 0.27)',
70
+ 'rgba(0, 0, 0, 0.29)',
71
+ 'rgba(0, 0, 0, 0.30)',
72
+ 'rgba(0, 0, 0, 0.32)',
73
+ 'rgba(0, 0, 0, 0.34)',
74
+ ],
75
+ dark: [
76
+ 'rgba(255, 255, 255, 0.58)',
77
+ 'rgba(255, 255, 255, 0.60)',
78
+ 'rgba(255, 255, 255, 0.62)',
79
+ 'rgba(255, 255, 255, 0.63)',
80
+ 'rgba(255, 255, 255, 0.65)',
81
+ 'rgba(255, 255, 255, 0.67)',
82
+ 'rgba(255, 255, 255, 0.69)',
83
+ 'rgba(255, 255, 255, 0.70)',
84
+ 'rgba(255, 255, 255, 0.72)',
85
+ 'rgba(255, 255, 255, 0.74)',
86
+ ]
87
+ }
88
+
89
+ const LIGHT_COLORS = {
90
+ primary: {
91
+ 0: '#FFF7E6',
92
+ 5: '#FCEDD0',
93
+ 10: '#F9DAA3', // p-lighter
94
+ 20: '#F5BF64', // p-light
95
+ 30: '#fca54c',
96
+ 40: '#ff9225',
97
+ 50: '#FF9F06', // p-main
98
+ 60: '#DD9434', // p-dark
99
+ 70: '#AC7326', // p-darker
100
+ 80: '#c46500',
101
+ 90: '#995400',
102
+ 100: '#663800',
103
+ lighter: '#F9DAA3',
104
+ light: '#F5BF64',
105
+ main: '#FF9F06',
106
+ dark: '#DD9434',
107
+ darker: '#AC7326',
108
+ },
109
+ secondary: {
110
+ 0: '#E6F7FF',
111
+ 5: '#D1EDFF',
112
+ 10: '#ADE2FF',
113
+ 20: '#85D4FF',
114
+ 30: '#5CC5FF',
115
+ 40: '#33B7FF',
116
+ 50: '#007FFF',
117
+ 60: '#0075E6',
118
+ 70: '#006ACC',
119
+ 80: '#005FB3',
120
+ 90: '#005499',
121
+ 100: '#003866',
122
+ main: '#007FFF',
123
+ },
124
+ danger: {
125
+ 5: '#FEECF0',
126
+ 10: '#FCD4DE',
127
+ 20: '#F799B1',
128
+ 30: '#F36689',
129
+ 40: '#EF3E5E',
130
+ 50: '#EB003B',
131
+ 60: '#D50136',
132
+ 70: '#8D0023',
133
+ 80: '#5E0018',
134
+ 90: '#2F000C',
135
+ main: '#EB003B',
136
+ },
137
+ warning: {
138
+ 5: '#FFF8E9',
139
+ 10: '#FFEAC1',
140
+ 20: '#FFE2A7',
141
+ 30: '#FFD47C',
142
+ 40: '#FFC550',
143
+ 50: '#FFB724',
144
+ 60: '#98690A',
145
+ 70: '#66490E',
146
+ 80: '#4D370B',
147
+ 90: '#332507',
148
+ main: '#FFB724',
149
+ },
150
+ success: {
151
+ 5: '#EEF7F0',
152
+ 10: '#CEE9D4',
153
+ 20: '#B2DCBB',
154
+ 30: '#8CCA99',
155
+ 40: '#33A14B',
156
+ 50: '#008A1E',
157
+ 60: '#006E18',
158
+ 70: '#005312',
159
+ 80: '#00370C',
160
+ 90: '#002207',
161
+ main: '#008A1E',
162
+ },
163
+ information: {
164
+ 5: '#E9F0FF',
165
+ 10: '#D4E1FF',
166
+ 20: '#A9C3FF',
167
+ 30: '#7DA4FF',
168
+ 40: '#5286FF',
169
+ 50: '#2768FF',
170
+ 60: '#1F53CC',
171
+ 70: '#173E99',
172
+ 80: '#0C1F4D',
173
+ 90: '#040A1A',
174
+ main: '#2768FF',
175
+ },
176
+ grey: {
177
+ 0: '#FFFFFF',
178
+ 5: '#F8F8F8',
179
+ 10: '#F9FAFB',
180
+ 20: '#F4F6F8',
181
+ 30: '#DFE3E8',
182
+ 40: '#C4CDD5',
183
+ 50: '#919EAB',
184
+ 60: '#637381',
185
+ 70: '#454F5B',
186
+ 80: '#1C252E',
187
+ 90: '#141A21',
188
+ 100: '#000000',
189
+ main: '#F4F6F8',
190
+ },
191
+ };
192
+
193
+ const DARK_COLORS = {
194
+ primary: {
195
+ ...LIGHT_COLORS.primary,
196
+ main: '#FF9F06',
197
+ },
198
+ secondary: {
199
+ ...LIGHT_COLORS.secondary,
200
+ main: '#007FFF',
201
+ },
202
+ danger: {
203
+ ...LIGHT_COLORS.danger,
204
+ main: '#EB003B',
205
+ },
206
+ warning: {
207
+ ...LIGHT_COLORS.warning,
208
+ main: '#FFB724',
209
+ },
210
+ success: {
211
+ ...LIGHT_COLORS.success,
212
+ main: '#008A1E',
213
+ },
214
+ information: {
215
+ ...LIGHT_COLORS.information,
216
+ main: '#2768FF',
217
+ },
218
+ grey: {
219
+ 0: '#000000',
220
+ 5: '#141414', // layer1
221
+ 10: '#1F1F1F', // layer2
222
+ 20: '#2C2C2C', // neutral
223
+ 30: '#3D3D3D',
224
+ 40: '#4F4F4F',
225
+ 50: '#606060',
226
+ 60: '#737373',
227
+ 70: '#8C8C8C',
228
+ 80: '#bfbfbf',
229
+ 90: '#ededed',
230
+ 100: '#FFFFFF',
231
+ main: '#2C2C2C',
232
+ },
233
+ };
234
+
235
+ const MAIN_COLORS = {
236
+ light: {
237
+ primary: LIGHT_COLORS.primary.main,
238
+ secondary: LIGHT_COLORS.secondary.main,
239
+ danger: LIGHT_COLORS.danger.main,
240
+ warning: LIGHT_COLORS.warning.main,
241
+ success: LIGHT_COLORS.success.main,
242
+ information: LIGHT_COLORS.information.main,
243
+ grey: LIGHT_COLORS.grey.main
244
+ },
245
+ dark: {
246
+ primary: DARK_COLORS.primary.main,
247
+ secondary: DARK_COLORS.secondary.main,
248
+ danger: DARK_COLORS.danger.main,
249
+ warning: DARK_COLORS.warning.main,
250
+ success: DARK_COLORS.success.main,
251
+ information: DARK_COLORS.information.main,
252
+ grey: DARK_COLORS.grey.main
253
+ }
254
+ }
255
+
256
+ const TEXT_COLORS = {
257
+ light: {
258
+ primary: LIGHT_COLORS.grey[80],
259
+ secondary: LIGHT_COLORS.grey[60],
260
+ disabled: LIGHT_COLORS.grey[50],
261
+ danger: LIGHT_COLORS.danger[60],
262
+ warning: LIGHT_COLORS.warning[60],
263
+ success: LIGHT_COLORS.success[60],
264
+ information: LIGHT_COLORS.information[60],
265
+ white: '#FFFFFF',
266
+ black: '#000000',
267
+ },
268
+ dark: {
269
+ primary: DARK_COLORS.grey[90],
270
+ secondary: DARK_COLORS.grey[70],
271
+ disabled: DARK_COLORS.grey[50],
272
+ danger: DARK_COLORS.danger[30],
273
+ warning: DARK_COLORS.warning[30],
274
+ success: DARK_COLORS.success[30],
275
+ information: DARK_COLORS.information[30],
276
+ white: '#FFFFFF',
277
+ black: '#000000',
278
+ },
279
+ };
280
+
281
+ const BORDER_COLORS = {
282
+ light: {
283
+ box: LIGHT_COLORS.grey[20],
284
+ active: LIGHT_COLORS.primary[50],
285
+ base: LIGHT_COLORS.grey[60],
286
+ danger: LIGHT_COLORS.danger[10],
287
+ warning: LIGHT_COLORS.warning[10],
288
+ success: LIGHT_COLORS.success[10],
289
+ information: LIGHT_COLORS.information[10],
290
+ },
291
+ dark: {
292
+ box: DARK_COLORS.grey[30],
293
+ active: DARK_COLORS.primary[50],
294
+ base: DARK_COLORS.grey[60],
295
+ danger: DARK_COLORS.danger[70],
296
+ warning: DARK_COLORS.warning[70],
297
+ success: DARK_COLORS.success[70],
298
+ information: DARK_COLORS.information[70],
299
+ },
300
+ };
301
+
302
+ const BACKGROUND_COLORS = {
303
+ light: {
304
+ layer1: LIGHT_COLORS.grey[5],
305
+ layer2: LIGHT_COLORS.grey[20],
306
+ neutral: LIGHT_COLORS.grey[30],
307
+ base: LIGHT_COLORS.grey[0],
308
+ danger: LIGHT_COLORS.danger[5],
309
+ warning: LIGHT_COLORS.warning[5],
310
+ success: LIGHT_COLORS.success[5],
311
+ information: LIGHT_COLORS.information[5],
312
+ },
313
+ dark: {
314
+ layer1: DARK_COLORS.grey[5],
315
+ layer2: DARK_COLORS.grey[20],
316
+ neutral: DARK_COLORS.grey[30],
317
+ base: DARK_COLORS.grey[0],
318
+ danger: DARK_COLORS.danger[80],
319
+ warning: DARK_COLORS.warning[80],
320
+ success: DARK_COLORS.success[80],
321
+ information: DARK_COLORS.information[80],
322
+ },
323
+ };
324
+
325
+ const ACTION_COLORS = {
326
+ light: {
327
+ hover: LIGHT_COLORS.primary[60],
328
+ pressed: LIGHT_COLORS.primary[70],
329
+ disable: LIGHT_COLORS.grey[20],
330
+ },
331
+ dark: {
332
+ hover: DARK_COLORS.primary[60],
333
+ pressed: DARK_COLORS.primary[70],
334
+ disable: DARK_COLORS.grey[30],
335
+ },
336
+ };
337
+
338
+ const DIVIDER_COLOR = {
339
+ light: LIGHT_COLORS.grey[50] + transparency['20%'],
340
+ dark: DARK_COLORS.grey[50] + transparency['20%'],
341
+ };
342
+
343
+ export default function palette({
344
+ mode = 'light',
345
+ themeColors = {},
346
+ }: {
347
+ mode?: 'light' | 'dark';
348
+ themeColors?: { light?: Theme; dark?: Theme };
349
+ } = {}): Theme {
350
+ const colors = mode === 'light' ? LIGHT_COLORS : DARK_COLORS;
351
+
352
+ const theme: Theme = {
353
+ mode,
354
+ ...colors,
355
+ text: TEXT_COLORS[mode],
356
+ border: BORDER_COLORS[mode],
357
+ background: BACKGROUND_COLORS[mode],
358
+ action: ACTION_COLORS[mode],
359
+ divider: DIVIDER_COLOR[mode],
360
+ elevationShadow: SHADOW_COLORS[mode],
361
+ modalBgColor: MODAL_BG_COLOR[mode],
362
+ mainColor: MAIN_COLORS[mode]
363
+ };
364
+
365
+ // 사용자 정의 테마 컬러가 있을 경우 병합
366
+ if (themeColors?.[mode]) {
367
+ return {
368
+ ...theme,
369
+ ...themeColors[mode],
370
+ };
371
+ }
372
+
373
+ return theme;
374
+ }