@0610studio/zs-ui 0.0.13 → 0.0.15

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 (77) hide show
  1. package/build/index.d.ts +2 -1
  2. package/build/index.d.ts.map +1 -1
  3. package/build/index.js +4 -1
  4. package/build/index.js.map +1 -1
  5. package/build/model/index.d.ts +4 -0
  6. package/build/model/index.d.ts.map +1 -0
  7. package/build/model/index.js +4 -0
  8. package/build/model/index.js.map +1 -0
  9. package/build/types/index.d.ts +9 -0
  10. package/build/types/index.d.ts.map +1 -0
  11. package/build/types/index.js +2 -0
  12. package/build/types/index.js.map +1 -0
  13. package/package.json +6 -1
  14. package/.eslintrc.js +0 -5
  15. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  16. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  17. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  18. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  19. package/android/.gradle/8.9/gc.properties +0 -0
  20. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  21. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  22. package/android/.gradle/vcs-1/gc.properties +0 -0
  23. package/android/build.gradle +0 -43
  24. package/android/src/main/AndroidManifest.xml +0 -2
  25. package/android/src/main/java/kr/co/studio0610/zsui/ZsUiModule.kt +0 -47
  26. package/android/src/main/java/kr/co/studio0610/zsui/ZsUiView.kt +0 -7
  27. package/expo-module.config.json +0 -9
  28. package/ios/ZsUi.podspec +0 -27
  29. package/ios/ZsUiModule.swift +0 -44
  30. package/ios/ZsUiView.swift +0 -7
  31. package/src/ZsUi.types.ts +0 -7
  32. package/src/ZsUiModule.ts +0 -5
  33. package/src/ZsUiModule.web.ts +0 -13
  34. package/src/ZsUiView.tsx +0 -11
  35. package/src/ZsUiView.web.tsx +0 -11
  36. package/src/assets/SvgCheck.tsx +0 -16
  37. package/src/assets/SvgX.tsx +0 -22
  38. package/src/index.ts +0 -52
  39. package/src/model/types.ts +0 -104
  40. package/src/model/useNotify.ts +0 -14
  41. package/src/model/useNotifyProvider.tsx +0 -259
  42. package/src/model/useThemeProvider.tsx +0 -99
  43. package/src/model/utils.ts +0 -31
  44. package/src/notify/AlertNotify/index.tsx +0 -172
  45. package/src/notify/BottomSheetNotify/index.tsx +0 -177
  46. package/src/notify/BottomSheetNotify/model/useBottomSheetNotify.tsx +0 -270
  47. package/src/notify/BottomSheetNotify/types/index.ts +0 -3
  48. package/src/notify/BottomSheetNotify/ui/BSTextInput/index.tsx +0 -28
  49. package/src/notify/BottomSheetNotify/ui/ContentsComponent/index.tsx +0 -86
  50. package/src/notify/LoadingNotify/index.tsx +0 -46
  51. package/src/notify/PopOver/PopOverButton.tsx +0 -56
  52. package/src/notify/PopOver/PopOverMenu.tsx +0 -95
  53. package/src/notify/SnackbarNotify/index.tsx +0 -43
  54. package/src/notify/SnackbarNotify/ui/SnackbarItem.tsx +0 -103
  55. package/src/notify/index.ts +0 -21
  56. package/src/notify/ui/ModalBackground.tsx +0 -46
  57. package/src/theme/index.ts +0 -3
  58. package/src/theme/palette.ts +0 -384
  59. package/src/theme/types.ts +0 -170
  60. package/src/theme/typography.ts +0 -199
  61. package/src/ui/ThrottleButton/index.tsx +0 -119
  62. package/src/ui/ZSBottomButton/index.tsx +0 -151
  63. package/src/ui/ZSContainer/index.tsx +0 -92
  64. package/src/ui/ZSPressable/index.tsx +0 -82
  65. package/src/ui/ZSRadioGroup/index.tsx +0 -141
  66. package/src/ui/ZSText/index.tsx +0 -22
  67. package/src/ui/ZSTextField/index.tsx +0 -200
  68. package/src/ui/ZSTextField/ui/ButtonClose.tsx +0 -20
  69. package/src/ui/ZSTextField/ui/ErrorComponent.tsx +0 -25
  70. package/src/ui/ZSView/index.tsx +0 -30
  71. package/src/ui/atoms/AnimatedWrapper.tsx +0 -90
  72. package/src/ui/atoms/ScrollViewAtom.tsx +0 -17
  73. package/src/ui/atoms/TextAtom.tsx +0 -15
  74. package/src/ui/atoms/ViewAtom.tsx +0 -15
  75. package/src/ui/index.ts +0 -27
  76. package/src/ui/types.ts +0 -12
  77. package/tsconfig.json +0 -9
@@ -1,259 +0,0 @@
1
- import { useCallback, useRef, useState } from 'react';
2
- import { Dimensions, Keyboard, TextProps, TouchableOpacityProps } from 'react-native';
3
- import NotifyContext from './useNotify';
4
- import { AlertActions, BottomSheetRef, HideOption, NotifyProviderProps, PopOverMenuProps, ShowAlertProps, ShowBottomSheetProps, ShowSnackBarProps, SnackItem } from './types';
5
- import AlertNotify from '../notify/AlertNotify';
6
- import SnackbarNotify from '../notify/SnackbarNotify';
7
- import BottomSheetNotify from '../notify/BottomSheetNotify';
8
- import LoadingNotify from '../notify/LoadingNotify';
9
- import PopOverMenu from '../notify/PopOver/PopOverMenu';
10
-
11
- const BS_MAX_HEIGHT = Dimensions.get('window').height - 120;
12
-
13
- export function NotifyProvider({
14
- customSnackbar,
15
- loaderComponent,
16
- children
17
- }: NotifyProviderProps) {
18
- // Alert
19
- const [title, setTitle] = useState<string>('');
20
- const [informative, setInformative] = useState<string>('');
21
- const [alertVisible, setAlertVisible] = useState<boolean>(false);
22
- const [actions, setActions] = useState<AlertActions>();
23
- const [isBackgroundTouchClose, setIsBackgroundTouchClose] = useState<boolean>(true);
24
- const [titleStyle, setTitleStyle] = useState<TextProps['style']>();
25
- const [informativeStyle, setInformativeStyle] = useState<TextProps['style']>();
26
- const [secondaryButtonStyle, setSecondaryButtonStyle] = useState<TouchableOpacityProps['style']>();
27
- const [primaryButtonStyle, setPrimaryButtonStyle] = useState<TouchableOpacityProps['style']>();
28
- const [secondaryButtonTextStyle, setSecondaryButtonTextStyle] = useState<TextProps['style']>();
29
- const [primaryButtonTextStyle, setPrimaryButtonTextStyle] = useState<TextProps['style']>();
30
- const [singleButtonTextStyle, setSingleButtonTextStyle] = useState<TextProps['style']>();
31
-
32
- // Snackbar
33
- const [snackItemStack, setSnackItemStack] = useState<SnackItem[]>([]);
34
-
35
- // BottomSheet
36
- const [contentsGestureEnable, setContentsGestureEnable] = useState<boolean>(false);
37
- const [bottomSheetVisible, setBottomSheetVisible] = useState<boolean>(false);
38
- const [bottomSheetBackgroundColor, setBottomSheetBackgroundColor] = useState<string>();
39
- const [bottomSheetComponent, setBottomSheetComponent] = useState<React.ReactNode>(false);
40
- const [bottomSheetPadding, setBottomSheetPadding] = useState<number | undefined>(undefined);
41
- const [bottomSheetMarginX, setBottomSheetMarginX] = useState<number | undefined>(undefined);
42
- const [bottomSheetMaxHeight, setBottomSheetMaxHeight] = useState<number>(BS_MAX_HEIGHT);
43
- const [bottomSheetScrollView, setBottomSheetScrollView] = useState<boolean>(true);
44
- const [isBottomRadius, setIsBottomRadius] = useState<boolean>(true);
45
- const [handleVisible, setHandleVisible] = useState<boolean>(true);
46
- const [marginBottomBS, setMarginBottomBs] = useState<number | undefined>(undefined);
47
- const [showsVerticalScrollIndicator, setShowsVerticalScrollIndicator] = useState<boolean>(false);
48
- const [headerComponent, setHeaderComponent] = useState<React.ReactNode | undefined>(undefined);
49
- const bottomSheetRef = useRef<BottomSheetRef | null>(null);
50
-
51
- // Loading
52
- const [loaderVisible, setLoaderVisible] = useState<boolean>(false);
53
-
54
- // PopOver
55
- const [popOverVisible, setPopOverVisible] = useState<boolean>(false);
56
- const [popOverLocation, setPopOverLocation] = useState<{ px: PopOverMenuProps['px'], py: PopOverMenuProps['py'] }>({ px: 0, py: 0 });
57
- const [popOverComponent, setPopOverComponent] = useState<React.ReactNode>(false);
58
-
59
- // ---
60
- const [fontFamily, setFontFamily] = useState<string | undefined | { title?: string; info?: string; label?: string; }>(undefined);
61
-
62
-
63
- const showAlert = ({
64
- title,
65
- informative,
66
- actions,
67
- isBackgroundTouchClose = true,
68
- titleStyle,
69
- informativeStyle,
70
- secondaryButtonStyle,
71
- primaryButtonStyle,
72
- secondaryButtonTextStyle,
73
- primaryButtonTextStyle,
74
- singleButtonTextStyle,
75
- }: ShowAlertProps) => {
76
- Keyboard.dismiss();
77
- setTitle(title);
78
- setInformative(informative);
79
- setActions(actions || {} as AlertActions);
80
- setIsBackgroundTouchClose(isBackgroundTouchClose);
81
- setAlertVisible(true);
82
-
83
- setTitleStyle(titleStyle);
84
- setInformativeStyle(informativeStyle);
85
- setSecondaryButtonStyle(secondaryButtonStyle);
86
- setPrimaryButtonStyle(primaryButtonStyle);
87
- setSecondaryButtonTextStyle(secondaryButtonTextStyle);
88
- setPrimaryButtonTextStyle(primaryButtonTextStyle);
89
- setSingleButtonTextStyle(singleButtonTextStyle);
90
-
91
- setFontFamily(fontFamily);
92
- };
93
-
94
- const showBottomSheet = ({
95
- isHandleVisible = true,
96
- component,
97
- contentsGestureEnable = true,
98
- marginHorizontal,
99
- padding,
100
- marginBottom,
101
- backgroundColor,
102
- isBottomRadius = true,
103
- maxHeight,
104
- isScrollView = true,
105
- showsVerticalScrollIndicator = false,
106
- headerComponent = undefined
107
- }: ShowBottomSheetProps) => {
108
- Keyboard.dismiss();
109
- padding && setBottomSheetPadding(padding);
110
- marginBottom && setMarginBottomBs(marginBottom);
111
- marginHorizontal && setBottomSheetMarginX(marginHorizontal);
112
- backgroundColor && setBottomSheetBackgroundColor(backgroundColor);
113
- maxHeight && setBottomSheetMaxHeight(maxHeight);
114
- setShowsVerticalScrollIndicator(showsVerticalScrollIndicator);
115
- setHeaderComponent(headerComponent);
116
- setContentsGestureEnable(contentsGestureEnable);
117
- setHandleVisible(isHandleVisible);
118
- setBottomSheetScrollView(isScrollView);
119
- setIsBottomRadius(isBottomRadius);
120
- setBottomSheetComponent(component);
121
- bottomSheetRef.current?.handleVisible(true);
122
- };
123
-
124
- const showLoader = () => {
125
- setLoaderVisible(true);
126
- };
127
-
128
- const showPopOverMenu = ({
129
- px,
130
- py,
131
- component
132
- }: PopOverMenuProps) => {
133
- setPopOverLocation({ px, py });
134
- setPopOverComponent(component);
135
- setPopOverVisible(true);
136
- }
137
-
138
- const showSnackBar = ({
139
- message,
140
- type = 'success',
141
- index = Date.now(),
142
- snackbarDuration = 3000
143
- }: ShowSnackBarProps) => {
144
- // TODO: 스택 쌓고싶은데 삭제될 때 참조를 잃어서 삭제가 안되는 문제가 있음.
145
- setSnackItemStack((prev) => {
146
- if (prev.length === 0) {
147
- return [...prev, { message, type, index: index, snackbarDuration: snackbarDuration }];
148
- } else {
149
- return prev;
150
- };
151
- });
152
- };
153
-
154
- const hideSnackBar = (index: number) => {
155
- setSnackItemStack((prev) => prev.filter((item) => item.index !== index));
156
- };
157
-
158
- const hideNotify = useCallback((option: HideOption) => {
159
- switch (option) {
160
- case 'alert':
161
- setAlertVisible(false);
162
- break;
163
- case 'snack':
164
- setSnackItemStack([]);
165
- break;
166
- case 'bottomSheet':
167
- bottomSheetRef.current?.handleVisible(false);
168
- break;
169
- case 'loader':
170
- setLoaderVisible(false);
171
- break;
172
- case 'popOver':
173
- setPopOverVisible(false);
174
- break;
175
- case 'all':
176
- setAlertVisible(false);
177
- setSnackItemStack([]);
178
- setLoaderVisible(false);
179
- setPopOverVisible(false);
180
- bottomSheetRef.current?.handleVisible(false);
181
- break;
182
- default:
183
- break;
184
- };
185
- }, []);
186
-
187
-
188
- return (
189
- <NotifyContext.Provider value={{
190
- alertVisible,
191
- setAlertVisible,
192
- // ---
193
- snackItemStack,
194
- hideSnackBar,
195
- // ---
196
- bottomSheetVisible,
197
- setBottomSheetVisible,
198
- // ---
199
- loaderVisible,
200
- // ---
201
- popOverVisible,
202
- setPopOverVisible,
203
- // ---
204
- showAlert,
205
- showSnackBar,
206
- showBottomSheet,
207
- showLoader,
208
- showPopOverMenu,
209
- // ---
210
- hideNotify,
211
- }}>
212
- {children}
213
-
214
- <BottomSheetNotify
215
- ref={bottomSheetRef}
216
- bottomSheetComponent={bottomSheetComponent}
217
- contentsGestureEnable={contentsGestureEnable}
218
- bottomSheetPadding={bottomSheetPadding}
219
- marginBottomBS={marginBottomBS}
220
- isHandleVisible={handleVisible}
221
- bottomSheetMarginX={bottomSheetMarginX}
222
- isBottomRadius={isBottomRadius}
223
- bottomSheetBackgroundColor={bottomSheetBackgroundColor}
224
- maxHeight={bottomSheetMaxHeight}
225
- isScrollView={bottomSheetScrollView}
226
- showsVerticalScrollIndicator={showsVerticalScrollIndicator}
227
- headerComponent={headerComponent}
228
- />
229
-
230
- <PopOverMenu
231
- px={popOverLocation?.px}
232
- py={popOverLocation?.py}
233
- component={popOverComponent}
234
- />
235
-
236
- <SnackbarNotify
237
- customSnackbar={customSnackbar}
238
- />
239
-
240
- <AlertNotify
241
- title={title}
242
- informative={informative}
243
- actions={actions || {} as AlertActions}
244
- isBackgroundTouchClose={isBackgroundTouchClose}
245
- titleStyle={titleStyle}
246
- informativeStyle={informativeStyle}
247
- secondaryButtonStyle={secondaryButtonStyle}
248
- primaryButtonStyle={primaryButtonStyle}
249
- secondaryButtonTextStyle={secondaryButtonTextStyle}
250
- primaryButtonTextStyle={primaryButtonTextStyle}
251
- singleButtonTextStyle={singleButtonTextStyle}
252
- />
253
-
254
- <LoadingNotify
255
- loaderComponent={loaderComponent}
256
- />
257
- </NotifyContext.Provider>
258
- );
259
- }
@@ -1,99 +0,0 @@
1
- import React, { createContext, useContext, useMemo, useState, useEffect } from 'react';
2
- import { useColorScheme } from 'react-native';
3
- import AsyncStorage from '@react-native-async-storage/async-storage';
4
- import palette from '../theme/palette';
5
- import { Theme, ThemeFonts, TypographyVariantsProps } from '../theme/types';
6
- import typography from '../theme/typography';
7
-
8
- export interface ThemeProviderProps {
9
- themeFonts?: ThemeFonts;
10
- children: React.ReactNode;
11
- }
12
-
13
- export interface ThemeProps {
14
- palette: Palette;
15
- typography: TypographyVariantsProps;
16
- }
17
-
18
- export interface Palette extends Theme {
19
- mode: 'light' | 'dark';
20
- isUsingSystemColorScheme: boolean;
21
- setUseSystemColorScheme: (useSystem: boolean) => void;
22
- toggleTheme: () => void;
23
- }
24
-
25
- const ThemeContext = createContext<ThemeProps | null>(null);
26
-
27
- export const useTheme = () => {
28
- const context = useContext(ThemeContext);
29
- if (!context) {
30
- throw new Error('useTheme must be used within a ThemeProvider');
31
- }
32
- return context;
33
- }
34
-
35
- export const ThemeProvider: React.FC<ThemeProviderProps> = ({ themeFonts, children }) => {
36
- const systemColorScheme = useColorScheme(); // 시스템 다크 모드 감지
37
- const [isUsingSystemColorScheme, setUseSystemColorScheme] = useState(true);
38
- const [mode, setMode] = useState<'light' | 'dark'>(systemColorScheme === 'dark' ? 'dark' : 'light');
39
-
40
- // AsyncStorage에서 시스템 모드 사용 설정 값 로드
41
- useEffect(() => {
42
- const loadSettings = async () => {
43
- try {
44
- const storedUseSystemColorScheme = await AsyncStorage.getItem('useSystemColorScheme');
45
- if (storedUseSystemColorScheme !== null) {
46
- setUseSystemColorScheme(storedUseSystemColorScheme === 'true');
47
- }
48
- const storedMode = await AsyncStorage.getItem('themeMode');
49
- if (storedMode) {
50
- setMode(storedMode === 'dark' ? 'dark' : 'light');
51
- } else {
52
- setMode(systemColorScheme === 'dark' ? 'dark' : 'light');
53
- }
54
- } catch (error) {
55
- console.error('Failed to load theme settings', error);
56
- }
57
- };
58
- loadSettings();
59
- }, [systemColorScheme]);
60
-
61
- // 시스템 다크 모드 변경에 따른 효과 적용
62
- useEffect(() => {
63
- if (isUsingSystemColorScheme) {
64
- setMode(systemColorScheme === 'dark' ? 'dark' : 'light');
65
- }
66
- }, [systemColorScheme, isUsingSystemColorScheme]);
67
-
68
- // 테마 토글 함수
69
- const toggleTheme = async () => {
70
- setUseSystemColorScheme(false); // 사용자 지정 모드로 전환
71
- setMode((prevMode) => {
72
- const newMode = prevMode === 'light' ? 'dark' : 'light';
73
- AsyncStorage.setItem('themeMode', newMode); // 로컬스토리지에 저장
74
- return newMode;
75
- });
76
- };
77
-
78
- // 시스템 모드 사용 설정 변경 함수
79
- const handleSetUseSystemColorScheme = async (useSystem: boolean) => {
80
- setUseSystemColorScheme(useSystem);
81
- await AsyncStorage.setItem('useSystemColorScheme', useSystem.toString());
82
- };
83
-
84
- const themeValue = useMemo(() => ({
85
- palette: {
86
- isUsingSystemColorScheme,
87
- setUseSystemColorScheme: handleSetUseSystemColorScheme,
88
- toggleTheme,
89
- ...palette({ mode }), // 선택된 모드에 따른 팔레트 적용
90
- },
91
- typography: typography({ themeFonts }),
92
- }), [mode, isUsingSystemColorScheme, typography, themeFonts]);
93
-
94
- return (
95
- <ThemeContext.Provider value={themeValue}>
96
- {children}
97
- </ThemeContext.Provider>
98
- );
99
- }
@@ -1,31 +0,0 @@
1
- import { StyleProp, TextStyle } from "react-native";
2
-
3
- /**
4
- * 사각형의 너비와 높이에 따라 비슷한 비율의 테두리 반지름을 계산합니다.
5
- * @param width 사각형의 너비입니다.
6
- * @param height 사각형의 높이입니다.
7
- * @param borderRadius 기본 테두리 반지름입니다.
8
- * @returns 계산된 테두리 반지름입니다.
9
- */
10
- export const calculateRadius = (width: number, height: number, borderRadius: number) => {
11
- const radiusRatio = Math.max((width / height), (height / width));
12
- const calc = borderRadius * (radiusRatio > 1 ? radiusRatio / 2 : radiusRatio);
13
- return calc;
14
- };
15
-
16
- export const withPromise = <T extends unknown[]>(fn: (...args: T) => Promise<unknown>): ((...args: T) => void) => {
17
- return (...args) => { void fn(...args) };
18
- };
19
-
20
- export const extractStyle = (
21
- style: StyleProp<TextStyle>,
22
- attribute: keyof TextStyle
23
- ): TextStyle[keyof TextStyle] | undefined => {
24
- if (Array.isArray(style)) {
25
- const foundStyle = style.find(item => typeof item === 'object' && item !== null && attribute in item);
26
- return foundStyle?.[attribute as keyof typeof foundStyle];
27
- } else if (typeof style === 'object' && style !== null && attribute in style) {
28
- return style[attribute];
29
- }
30
- return undefined;
31
- };
@@ -1,172 +0,0 @@
1
- import React, { useCallback, useEffect, useMemo } from 'react';
2
- import { Dimensions, KeyboardAvoidingView, Platform, Pressable, StyleSheet, TouchableOpacity, BackHandler, Text } from 'react-native';
3
- import Animated, { FadeInDown, FadeOutDown } from 'react-native-reanimated';
4
- import { AlertActions, ShowAlertProps } from '../../model/types';
5
- import { useNotify } from '../../model/useNotify';
6
- import { useTheme } from '../../model/useThemeProvider';
7
- import { ThemeBackground } from '../../theme';
8
- import { ZSText } from '../../ui';
9
- import ModalBackground from '../ui/ModalBackground';
10
- import ViewAtom from '../../ui/atoms/ViewAtom';
11
-
12
- const modalWidth = Dimensions.get('window').width - 60;
13
-
14
- function AlertNotify({
15
- actions,
16
- title,
17
- informative,
18
- isBackgroundTouchClose,
19
- titleStyle,
20
- informativeStyle,
21
- secondaryButtonStyle,
22
- primaryButtonStyle,
23
- secondaryButtonTextStyle,
24
- primaryButtonTextStyle,
25
- singleButtonTextStyle,
26
- }: ShowAlertProps) {
27
- const { alertVisible, setAlertVisible } = useNotify();
28
- const { palette: { background, text, primary: primaryColor } } = useTheme();
29
-
30
- const styles = useMemo(
31
- () => createStyles({ background }),
32
- [background, text, primaryColor]
33
- );
34
-
35
- // 버튼 클릭 핸들러 함수, 콜백 메모이제이션으로 성능 최적화
36
- const handleButtonPress = useCallback(
37
- (onPressFunction?: () => void) => () => {
38
- if (onPressFunction) {
39
- onPressFunction();
40
- }
41
- setAlertVisible(false);
42
- },
43
- [setAlertVisible]
44
- );
45
-
46
- // 뒤로가기 버튼 핸들러 함수
47
- const backPressHandler = useCallback(() => {
48
- if (alertVisible) {
49
- setAlertVisible(false);
50
- return true;
51
- }
52
- return false;
53
- }, [alertVisible, setAlertVisible]);
54
-
55
- // 뒤로가기 버튼 리스너 설정
56
- useEffect(() => {
57
- const backHandler = BackHandler.addEventListener('hardwareBackPress', backPressHandler);
58
- return () => backHandler.remove();
59
- }, [backPressHandler]);
60
-
61
- // content를 useMemo로 감싸서 불필요한 재렌더링 방지
62
- const content = useMemo(() => {
63
- const { primary, secondary } = actions || {} as AlertActions;
64
-
65
- return (
66
- <Animated.View
67
- entering={FadeInDown.duration(300)}
68
- exiting={FadeOutDown.duration(100)}
69
- >
70
- <Pressable style={[styles.contentContainer, { width: modalWidth }]}>
71
- {title && (
72
- <ZSText typo='title.2' style={[styles.title, titleStyle]}>{title}</ZSText>
73
- )}
74
- {informative && (
75
- <ZSText typo='body.3' style={[styles.informative, informativeStyle]}>{informative}</ZSText>
76
- )}
77
- {actions && (
78
- <ViewAtom style={styles.buttonContainer}>
79
- {secondary ? (
80
- <>
81
- <TouchableOpacity
82
- style={[
83
- styles.button,
84
- { backgroundColor: background.neutral, marginRight: 8 },
85
- secondaryButtonStyle
86
- ]}
87
- onPress={handleButtonPress(secondary?.onPress)}
88
- >
89
- <ZSText typo='subTitle.2' style={[secondaryButtonTextStyle]}>{secondary.label}</ZSText>
90
- </TouchableOpacity>
91
-
92
- <TouchableOpacity
93
- style={[styles.button, { backgroundColor: primaryColor.main }, primaryButtonStyle]}
94
- onPress={handleButtonPress(primary?.onPress)}
95
- >
96
- <ZSText typo='subTitle.2' color='white' style={[secondaryButtonTextStyle]}>{primary?.label || '확인'}</ZSText>
97
- </TouchableOpacity>
98
- </>
99
- ) : (
100
- <TouchableOpacity
101
- style={[styles.button, { backgroundColor: primaryColor.main }, primaryButtonStyle]}
102
- onPress={handleButtonPress(primary?.onPress)}
103
- >
104
- <ZSText typo='subTitle.2' color='white' style={[secondaryButtonTextStyle]}>{primary?.label || '확인'}</ZSText>
105
- </TouchableOpacity>
106
- )}
107
- </ViewAtom>
108
- )}
109
- </Pressable>
110
- </Animated.View>
111
- );
112
- }, [title, informative, actions, handleButtonPress, titleStyle, informativeStyle, secondaryButtonStyle, primaryButtonStyle, secondaryButtonTextStyle, primaryButtonTextStyle, singleButtonTextStyle]);
113
-
114
- return alertVisible ? (
115
- <ModalBackground onPress={() => { if (isBackgroundTouchClose) setAlertVisible(false); }}>
116
- <KeyboardAvoidingView
117
- style={styles.avoidingView}
118
- behavior={Platform.OS === 'ios' ? 'padding' : undefined}
119
- enabled
120
- >
121
- {content}
122
- </KeyboardAvoidingView>
123
- </ModalBackground>
124
- ) : null;
125
- }
126
-
127
- export default AlertNotify;
128
-
129
- const createStyles = ({
130
- background,
131
- }: {
132
- background: ThemeBackground;
133
- }) =>
134
- StyleSheet.create({
135
- title: {
136
- marginBottom: 8,
137
- width: '100%',
138
- paddingHorizontal: 4
139
- },
140
- informative: {
141
- marginTop: 8,
142
- width: '100%',
143
- paddingHorizontal: 4
144
- },
145
- buttonContainer: {
146
- flexDirection: 'row',
147
- width: '100%',
148
- marginTop: 24,
149
- alignItems: 'center',
150
- justifyContent: 'flex-end',
151
- },
152
- button: {
153
- flex: 1,
154
- justifyContent: 'center',
155
- alignItems: 'center',
156
- paddingVertical: 14,
157
- borderRadius: 12,
158
- },
159
- avoidingView: {
160
- flex: 1,
161
- justifyContent: 'center'
162
- },
163
- contentContainer: {
164
- alignItems: 'center',
165
- backgroundColor: background.base,
166
- borderRadius: 22,
167
- paddingBottom: 18,
168
- paddingTop: 24,
169
- paddingHorizontal: 20
170
- },
171
- });
172
-