cpk-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 (69) hide show
  1. package/README.md +27 -0
  2. package/components/modals/AlertDialog/AlertDialog.js +80 -0
  3. package/components/modals/AlertDialog/AlertDialog.stories.tsx +80 -0
  4. package/components/modals/AlertDialog/AlertDialog.tsx +194 -0
  5. package/components/modals/Snackbar/Snackbar.js +94 -0
  6. package/components/modals/Snackbar/Snackbar.stories.tsx +98 -0
  7. package/components/modals/Snackbar/Snackbar.tsx +174 -0
  8. package/components/modals/Snackbar/const.js +5 -0
  9. package/components/modals/Snackbar/const.ts +4 -0
  10. package/components/uis/Accordion/Accordion.js +11 -0
  11. package/components/uis/Accordion/Accordion.stories.tsx +38 -0
  12. package/components/uis/Accordion/Accordion.test.tsx +128 -0
  13. package/components/uis/Accordion/Accordion.tsx +58 -0
  14. package/components/uis/Accordion/AccordionItem.js +102 -0
  15. package/components/uis/Accordion/AccordionItem.tsx +213 -0
  16. package/components/uis/Button/Button.js +161 -0
  17. package/components/uis/Button/Button.stories.tsx +81 -0
  18. package/components/uis/Button/Button.test.tsx +560 -0
  19. package/components/uis/Button/Button.tsx +335 -0
  20. package/components/uis/Checkbox/Checkbox.js +70 -0
  21. package/components/uis/Checkbox/Checkbox.stories.tsx +46 -0
  22. package/components/uis/Checkbox/Checkbox.test.tsx +139 -0
  23. package/components/uis/Checkbox/Checkbox.tsx +150 -0
  24. package/components/uis/Icon/Icon.js +3780 -0
  25. package/components/uis/Icon/Icon.stories.tsx +45 -0
  26. package/components/uis/Icon/Icon.test.tsx +19 -0
  27. package/components/uis/Icon/Icon.tsx +3800 -0
  28. package/components/uis/Icon/Pretendard-Bold.otf +0 -0
  29. package/components/uis/Icon/Pretendard-Regular.otf +0 -0
  30. package/components/uis/Icon/Pretendard-Thin.otf +0 -0
  31. package/components/uis/Icon/cpk.ttf +0 -0
  32. package/components/uis/Icon/selection.json +1 -0
  33. package/components/uis/IconButton/IconButton.js +120 -0
  34. package/components/uis/IconButton/IconButton.test.tsx +165 -0
  35. package/components/uis/IconButton/IconButton.tsx +252 -0
  36. package/components/uis/LoadingIndicator/LoadingIndicator.js +24 -0
  37. package/components/uis/LoadingIndicator/LoadingIndicator.tsx +79 -0
  38. package/components/uis/Rating/Rating.js +53 -0
  39. package/components/uis/Rating/Rating.test.tsx +72 -0
  40. package/components/uis/Rating/Rating.tsx +155 -0
  41. package/components/uis/StatusbarBrightness/StatusBarBrightness.js +13 -0
  42. package/components/uis/StatusbarBrightness/StatusBarBrightness.test.tsx +41 -0
  43. package/components/uis/StatusbarBrightness/StatusBarBrightness.tsx +17 -0
  44. package/components/uis/Styled/StyledComponents.js +130 -0
  45. package/components/uis/Styled/StyledComponents.tsx +200 -0
  46. package/components/uis/SwitchToggle/SwitchToggle.js +126 -0
  47. package/components/uis/SwitchToggle/SwitchToggle.test.tsx +70 -0
  48. package/components/uis/SwitchToggle/SwitchToggle.tsx +224 -0
  49. package/components/uis/Typography/Typography.js +90 -0
  50. package/components/uis/Typography/Typography.test.tsx +58 -0
  51. package/components/uis/Typography/Typography.tsx +132 -0
  52. package/hooks/useDebouncedColorScheme.js +21 -0
  53. package/hooks/useDebouncedColorScheme.tsx +30 -0
  54. package/index.js +16 -0
  55. package/index.tsx +18 -0
  56. package/package.json +35 -0
  57. package/providers/ThemeProvider.js +106 -0
  58. package/providers/ThemeProvider.tsx +180 -0
  59. package/providers/index.js +62 -0
  60. package/providers/index.tsx +125 -0
  61. package/react-native.config.cjs +5 -0
  62. package/utils/colors.js +124 -0
  63. package/utils/colors.ts +127 -0
  64. package/utils/createCtx.js +15 -0
  65. package/utils/createCtx.tsx +26 -0
  66. package/utils/guards.js +44 -0
  67. package/utils/guards.ts +93 -0
  68. package/utils/theme.js +5 -0
  69. package/utils/theme.ts +33 -0
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import {fireEvent, render} from '@testing-library/react-native';
3
+
4
+ import type {RatingProps} from './Rating';
5
+ import {Rating} from './Rating';
6
+ import {createComponent} from '../../../../test/testUtils';
7
+
8
+ const Component = (props?: RatingProps): JSX.Element =>
9
+ createComponent(<Rating {...props} />);
10
+
11
+ describe('Rating', () => {
12
+ test('renders five stars', () => {
13
+ const {getAllByTestId} = render(
14
+ Component({
15
+ testID: 'star',
16
+ }),
17
+ );
18
+ const stars = getAllByTestId('star');
19
+ expect(stars).toHaveLength(5);
20
+ });
21
+
22
+ test('renders half stars when allowHalfRating is true', () => {
23
+ const {getAllByTestId} = render(
24
+ Component({
25
+ testID: 'half-star',
26
+ allowHalfRating: true,
27
+ }),
28
+ );
29
+ const halfStars = getAllByTestId('half-star');
30
+ expect(halfStars).toHaveLength(5);
31
+ });
32
+
33
+ test('renders `dooboo` iconType', () => {
34
+ const {getAllByTestId} = render(
35
+ Component({
36
+ testID: 'star',
37
+ iconType: 'dooboo',
38
+ }),
39
+ );
40
+ const stars = getAllByTestId('star');
41
+ expect(stars).toHaveLength(5);
42
+ });
43
+
44
+ test('calls onRatingUpdate when a star is clicked', () => {
45
+ const handleRatingUpdate = jest.fn();
46
+ const {getAllByRole} = render(
47
+ Component({
48
+ onRatingUpdate: handleRatingUpdate,
49
+ }),
50
+ );
51
+ const thirdStar = getAllByRole('button')[0];
52
+
53
+ fireEvent.press(thirdStar);
54
+
55
+ expect(handleRatingUpdate).toHaveBeenCalledWith(0.5);
56
+ });
57
+
58
+ test('calls onRatingUpdate when a half star is clicked', () => {
59
+ const handleRatingUpdate = jest.fn();
60
+ const {getAllByRole} = render(
61
+ Component({
62
+ onRatingUpdate: handleRatingUpdate,
63
+ allowHalfRating: true,
64
+ }),
65
+ );
66
+ const thirdHalfStar = getAllByRole('button')[1];
67
+
68
+ fireEvent.press(thirdHalfStar);
69
+
70
+ expect(handleRatingUpdate).toHaveBeenCalledWith(1);
71
+ });
72
+ });
@@ -0,0 +1,155 @@
1
+ // React import is needed for expo-web
2
+ import React, {useState} from 'react';
3
+ import type {StyleProp, ViewStyle} from 'react-native';
4
+ import {Pressable, View} from 'react-native';
5
+ import styled, {css} from '@emotion/native';
6
+
7
+ import type {IconName} from '../Icon/Icon';
8
+ import {Icon} from '../Icon/Icon';
9
+
10
+ const Container = styled.View`
11
+ flex-direction: row;
12
+ `;
13
+
14
+ const StarContainer = styled.View`
15
+ padding: 1px;
16
+
17
+ flex-direction: row;
18
+ `;
19
+
20
+ type Styles = {
21
+ starContainer: StyleProp<ViewStyle>;
22
+ };
23
+
24
+ export type RatingProps = {
25
+ testID?: string;
26
+ styles?: Styles;
27
+ style?: StyleProp<ViewStyle>;
28
+ size?: number;
29
+ iconType?: 'star' | 'dooboo';
30
+ initialRating?: number;
31
+ direction?: 'horizontal' | 'vertical';
32
+ allowHalfRating?: boolean;
33
+ onRatingUpdate?: (score: number) => void;
34
+ disabled?: boolean;
35
+ color?: string;
36
+ };
37
+
38
+ export function Rating({
39
+ testID,
40
+ style,
41
+ styles,
42
+ initialRating = 0,
43
+ size = 24,
44
+ iconType = 'star',
45
+ onRatingUpdate,
46
+ direction = 'horizontal',
47
+ allowHalfRating = true,
48
+ disabled = false,
49
+ color,
50
+ }: RatingProps): JSX.Element {
51
+ const [rating, setRating] = useState(initialRating);
52
+ const iconPrefix = iconType === 'star' ? 'Star' : 'QuestBox';
53
+
54
+ const handlePress = (newRating: number, halfPressed?: boolean): void => {
55
+ const convertedRating = newRating + (!halfPressed ? 0.5 : 0);
56
+
57
+ setRating(convertedRating);
58
+
59
+ if (onRatingUpdate) {
60
+ onRatingUpdate(convertedRating);
61
+ }
62
+ };
63
+
64
+ const renderStarIcon = ({
65
+ key,
66
+ position,
67
+ }: {
68
+ key: string;
69
+ position: number;
70
+ }): JSX.Element => {
71
+ const filled = rating >= position + (allowHalfRating ? 0.5 : 0);
72
+ const iconName: IconName = filled ? `${iconPrefix}Fill` : `${iconPrefix}`;
73
+ const halfFilled =
74
+ rating >= position && rating < position + (allowHalfRating ? 0.5 : 0);
75
+
76
+ return (
77
+ <StarContainer
78
+ key={key}
79
+ style={[
80
+ css`
81
+ width: ${size + 'px'};
82
+ `,
83
+ styles?.starContainer,
84
+ ]}
85
+ testID={testID}
86
+ >
87
+ {halfFilled && allowHalfRating ? (
88
+ <View style={{position: 'absolute'}}>
89
+ <Icon
90
+ color={color}
91
+ name={`${iconPrefix}` as IconName}
92
+ size={size}
93
+ style={{position: 'absolute'}}
94
+ />
95
+ <Icon
96
+ color={color}
97
+ name={`${iconPrefix}HalfFill` as IconName}
98
+ size={size}
99
+ />
100
+ </View>
101
+ ) : (
102
+ <Icon
103
+ color={color}
104
+ name={iconName}
105
+ size={size}
106
+ style={{position: 'absolute'}}
107
+ />
108
+ )}
109
+ <Pressable
110
+ accessibilityRole="button"
111
+ disabled={disabled}
112
+ onPress={() => handlePress(position, true)}
113
+ >
114
+ <View
115
+ style={{
116
+ width: size / 2,
117
+ height: size,
118
+ backgroundColor: 'transparent',
119
+ }}
120
+ />
121
+ </Pressable>
122
+ <Pressable
123
+ accessibilityRole="button"
124
+ disabled={disabled}
125
+ onPress={() => handlePress(position)}
126
+ >
127
+ <View
128
+ style={{
129
+ width: size / 2,
130
+ height: size,
131
+ backgroundColor: 'transparent',
132
+ }}
133
+ />
134
+ </Pressable>
135
+ </StarContainer>
136
+ );
137
+ };
138
+
139
+ return (
140
+ <Container
141
+ style={[
142
+ css`
143
+ flex-direction: ${direction === 'horizontal' ? 'row' : 'column'};
144
+ `,
145
+ style,
146
+ ]}
147
+ >
148
+ {[...Array(5)].map((_, index) => {
149
+ const position = index + (allowHalfRating ? 0.5 : 1);
150
+
151
+ return renderStarIcon({key: `${_}-${index}`, position});
152
+ })}
153
+ </Container>
154
+ );
155
+ }
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { StatusBar } from 'react-native';
3
+ import { useTheme } from '../../../providers/ThemeProvider';
4
+ function StatusBarBrightness({ type }) {
5
+ const { themeType } = useTheme();
6
+ const statusColor = type
7
+ ? type
8
+ : themeType === 'light'
9
+ ? 'dark-content'
10
+ : 'light-content';
11
+ return _jsx(StatusBar, { barStyle: statusColor });
12
+ }
13
+ export default StatusBarBrightness;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import {View} from 'react-native';
3
+ import type {RenderAPI} from '@testing-library/react-native';
4
+ import {render} from '@testing-library/react-native';
5
+
6
+ import {createComponent} from '../../../../test/testUtils';
7
+ import StatusBarBrightness from './StatusBarBrightness';
8
+ import {ThemeProvider} from '../../../providers/ThemeProvider';
9
+
10
+ let testingLib: RenderAPI;
11
+
12
+ const Component = (): JSX.Element =>
13
+ createComponent(
14
+ <View>
15
+ <StatusBarBrightness />
16
+ </View>,
17
+ );
18
+
19
+ describe('[StatusBarBrightness]', () => {
20
+ it('should render without crashing', () => {
21
+ testingLib = render(Component());
22
+
23
+ const json = testingLib.toJSON();
24
+
25
+ expect(json).toBeTruthy();
26
+ });
27
+
28
+ it('should render [dark] mode', () => {
29
+ testingLib = render(
30
+ <ThemeProvider initialThemeType="dark">
31
+ <View>
32
+ <StatusBarBrightness />
33
+ </View>
34
+ </ThemeProvider>,
35
+ );
36
+
37
+ const json = testingLib.toJSON();
38
+
39
+ expect(json).toBeTruthy();
40
+ });
41
+ });
@@ -0,0 +1,17 @@
1
+ import type {StatusBarStyle} from 'react-native';
2
+ import {StatusBar} from 'react-native';
3
+ import {useTheme} from '../../../providers/ThemeProvider';
4
+
5
+ function StatusBarBrightness({type}: {type?: StatusBarStyle}): JSX.Element {
6
+ const {themeType} = useTheme();
7
+
8
+ const statusColor: StatusBarStyle = type
9
+ ? type
10
+ : themeType === 'light'
11
+ ? 'dark-content'
12
+ : 'light-content';
13
+
14
+ return <StatusBar barStyle={statusColor} />;
15
+ }
16
+
17
+ export default StatusBarBrightness;
@@ -0,0 +1,130 @@
1
+ import { Animated } from 'react-native';
2
+ import styled from '@emotion/native';
3
+ import { isEmptyObject } from '../../../utils/theme';
4
+ import { light } from '../../../utils/colors';
5
+ // 기본 theme 설정 함수
6
+ const resolveTheme = (theme) => isEmptyObject(theme) ? light : theme;
7
+ // ButtonWrapper Component
8
+ export const ButtonWrapper = styled.View `
9
+ border-width: ${({ outlined }) => (outlined ? '1px' : undefined)};
10
+ background-color: ${({ theme, type, outlined, loading, disabled }) => {
11
+ theme = resolveTheme(theme);
12
+ if (loading) {
13
+ return outlined ? undefined : theme.button[type].bg;
14
+ }
15
+ if (disabled) {
16
+ return undefined;
17
+ }
18
+ return outlined ? theme.bg.basic : theme.button[type ?? 'primary'].bg;
19
+ }};
20
+ border-color: ${({ theme, type, disabled }) => {
21
+ theme = resolveTheme(theme);
22
+ if (disabled) {
23
+ return theme.bg.basic;
24
+ }
25
+ return theme.button[type].bg;
26
+ }};
27
+ `;
28
+ // ButtonText Component
29
+ export const ButtonText = styled.Text `
30
+ font-family: Pretendard;
31
+ color: ${({ theme, outlined, type, disabled }) => {
32
+ theme = resolveTheme(theme);
33
+ if (outlined) {
34
+ return theme.text.basic;
35
+ }
36
+ if (disabled) {
37
+ return theme.text.disabled;
38
+ }
39
+ return theme.button[type].text;
40
+ }};
41
+ `;
42
+ // CheckboxWrapperOutlined Component
43
+ export const CheckboxWrapperOutlined = styled(Animated.View) `
44
+ border-width: 1px;
45
+ border-color: ${({ theme, type, disabled }) => {
46
+ theme = resolveTheme(theme);
47
+ if (disabled) {
48
+ return theme.bg.disabled;
49
+ }
50
+ return type === 'light'
51
+ ? theme.role.primary
52
+ : theme.button[type ?? 'primary'].bg;
53
+ }};
54
+ `;
55
+ // CheckboxWrapper Component
56
+ export const CheckboxWrapper = styled(Animated.View) `
57
+ background-color: ${({ theme, checked, type, disabled }) => {
58
+ theme = resolveTheme(theme);
59
+ if (disabled) {
60
+ return undefined;
61
+ }
62
+ if (!checked) {
63
+ return theme.bg.disabled;
64
+ }
65
+ return type === 'light'
66
+ ? theme.role.primary
67
+ : theme.button[type ?? 'primary'].bg;
68
+ }};
69
+ `;
70
+ // RadioButtonWrapper Component
71
+ export const RadioButtonWrapper = styled.View `
72
+ border-width: 1px;
73
+ border-color: ${({ theme, type, selected, disabled }) => {
74
+ theme = resolveTheme(theme);
75
+ if (disabled) {
76
+ return theme.bg.disabled;
77
+ }
78
+ if (!selected) {
79
+ return theme.text.basic;
80
+ }
81
+ return type === 'light'
82
+ ? theme.role.primary
83
+ : theme.button[type ?? 'primary'].bg;
84
+ }};
85
+ `;
86
+ // RadioWrapper Component
87
+ export const RadioWrapper = styled(Animated.View) `
88
+ background-color: ${({ theme, selected, type, disabled }) => {
89
+ theme = resolveTheme(theme);
90
+ if (disabled) {
91
+ return theme.bg.disabled;
92
+ }
93
+ if (!selected) {
94
+ return theme.role.primary;
95
+ }
96
+ return theme.button[type ?? 'primary'].bg;
97
+ }};
98
+ `;
99
+ // ColoredText Component
100
+ export const ColoredText = styled.Text `
101
+ font-family: Pretendard;
102
+ color: ${({ theme, selected, type, disabled }) => {
103
+ theme = resolveTheme(theme);
104
+ if (disabled) {
105
+ return undefined;
106
+ }
107
+ if (!selected) {
108
+ return theme.text.basic;
109
+ }
110
+ return type === 'light'
111
+ ? theme.role.primary
112
+ : theme.button[type ?? 'primary'].bg;
113
+ }};
114
+ `;
115
+ // SnackbarWrapper Component
116
+ export const SnackbarWrapper = styled(Animated.View) `
117
+ background-color: ${({ theme, type }) => {
118
+ theme = resolveTheme(theme);
119
+ return !type ? theme.bg.disabled : theme.button[type ?? 'light'].bg;
120
+ }};
121
+ flex-direction: row;
122
+ text-align: left;
123
+ align-items: center;
124
+ align-self: center;
125
+ position: absolute;
126
+ font-size: 16px;
127
+ padding: 10px 20px;
128
+ bottom: 20px;
129
+ border-radius: 20px;
130
+ `;
@@ -0,0 +1,200 @@
1
+ import {Animated} from 'react-native';
2
+ import styled from '@emotion/native';
3
+ import {CpkTheme, isEmptyObject} from '../../../utils/theme';
4
+ import {light} from '../../../utils/colors';
5
+
6
+ export type ButtonType =
7
+ | 'primary'
8
+ | 'secondary'
9
+ | 'success'
10
+ | 'danger'
11
+ | 'warning'
12
+ | 'info'
13
+ | 'light';
14
+
15
+ export type SnackbarType =
16
+ | 'primary'
17
+ | 'secondary'
18
+ | 'success'
19
+ | 'warning'
20
+ | 'info'
21
+ | 'danger';
22
+
23
+ // 기본 theme 설정 함수
24
+ const resolveTheme = (theme?: CpkTheme) =>
25
+ isEmptyObject(theme) ? light : theme!;
26
+
27
+ // ButtonWrapper Component
28
+ export const ButtonWrapper = styled.View<{
29
+ type?: ButtonType;
30
+ outlined?: boolean;
31
+ disabled?: boolean;
32
+ loading?: boolean;
33
+ }>`
34
+ border-width: ${({outlined}) => (outlined ? '1px' : undefined)};
35
+ background-color: ${({theme, type, outlined, loading, disabled}) => {
36
+ theme = resolveTheme(theme);
37
+
38
+ if (loading) {
39
+ return outlined ? undefined : theme.button[type!].bg;
40
+ }
41
+ if (disabled) {
42
+ return undefined;
43
+ }
44
+ return outlined ? theme.bg.basic : theme.button[type ?? 'primary'].bg;
45
+ }};
46
+ border-color: ${({theme, type, disabled}) => {
47
+ theme = resolveTheme(theme);
48
+
49
+ if (disabled) {
50
+ return theme.bg.basic;
51
+ }
52
+ return theme.button[type!].bg;
53
+ }};
54
+ `;
55
+
56
+ // ButtonText Component
57
+ export const ButtonText = styled.Text<{
58
+ outlined?: boolean;
59
+ type?: ButtonType | SnackbarType;
60
+ disabled?: boolean;
61
+ loading?: boolean;
62
+ theme?: CpkTheme;
63
+ }>`
64
+ font-family: Pretendard;
65
+ color: ${({theme, outlined, type, disabled}) => {
66
+ theme = resolveTheme(theme);
67
+
68
+ if (outlined) {
69
+ return theme.text.basic;
70
+ }
71
+ if (disabled) {
72
+ return theme.text.disabled;
73
+ }
74
+ return theme.button[type!].text;
75
+ }};
76
+ `;
77
+
78
+ // CheckboxWrapperOutlined Component
79
+ export const CheckboxWrapperOutlined = styled(Animated.View)<{
80
+ type: ButtonType;
81
+ disabled?: boolean;
82
+ checked?: boolean;
83
+ }>`
84
+ border-width: 1px;
85
+ border-color: ${({theme, type, disabled}) => {
86
+ theme = resolveTheme(theme);
87
+
88
+ if (disabled) {
89
+ return theme.bg.disabled;
90
+ }
91
+ return type === 'light'
92
+ ? theme.role.primary
93
+ : theme.button[type ?? 'primary'].bg;
94
+ }};
95
+ `;
96
+
97
+ // CheckboxWrapper Component
98
+ export const CheckboxWrapper = styled(Animated.View)<{
99
+ type: ButtonType;
100
+ disabled?: boolean;
101
+ checked?: boolean;
102
+ }>`
103
+ background-color: ${({theme, checked, type, disabled}) => {
104
+ theme = resolveTheme(theme);
105
+
106
+ if (disabled) {
107
+ return undefined;
108
+ }
109
+ if (!checked) {
110
+ return theme.bg.disabled;
111
+ }
112
+ return type === 'light'
113
+ ? theme.role.primary
114
+ : theme.button[type ?? 'primary'].bg;
115
+ }};
116
+ `;
117
+
118
+ // RadioButtonWrapper Component
119
+ export const RadioButtonWrapper = styled.View<{
120
+ type: ButtonType;
121
+ selected?: boolean;
122
+ disabled?: boolean;
123
+ }>`
124
+ border-width: 1px;
125
+ border-color: ${({theme, type, selected, disabled}) => {
126
+ theme = resolveTheme(theme);
127
+
128
+ if (disabled) {
129
+ return theme.bg.disabled;
130
+ }
131
+ if (!selected) {
132
+ return theme.text.basic;
133
+ }
134
+ return type === 'light'
135
+ ? theme.role.primary
136
+ : theme.button[type ?? 'primary'].bg;
137
+ }};
138
+ `;
139
+
140
+ // RadioWrapper Component
141
+ export const RadioWrapper = styled(Animated.View)<{
142
+ type: ButtonType;
143
+ disabled?: boolean;
144
+ selected?: boolean;
145
+ }>`
146
+ background-color: ${({theme, selected, type, disabled}) => {
147
+ theme = resolveTheme(theme);
148
+
149
+ if (disabled) {
150
+ return theme.bg.disabled;
151
+ }
152
+ if (!selected) {
153
+ return theme.role.primary;
154
+ }
155
+ return theme.button[type ?? 'primary'].bg;
156
+ }};
157
+ `;
158
+
159
+ // ColoredText Component
160
+ export const ColoredText = styled.Text<{
161
+ type: ButtonType;
162
+ disabled?: boolean;
163
+ selected?: boolean;
164
+ }>`
165
+ font-family: Pretendard;
166
+ color: ${({theme, selected, type, disabled}) => {
167
+ theme = resolveTheme(theme);
168
+
169
+ if (disabled) {
170
+ return undefined;
171
+ }
172
+ if (!selected) {
173
+ return theme.text.basic;
174
+ }
175
+ return type === 'light'
176
+ ? theme.role.primary
177
+ : theme.button[type ?? 'primary'].bg;
178
+ }};
179
+ `;
180
+
181
+ // SnackbarWrapper Component
182
+ export const SnackbarWrapper = styled(Animated.View)<{
183
+ type?: SnackbarType;
184
+ checked?: boolean;
185
+ }>`
186
+ background-color: ${({theme, type}) => {
187
+ theme = resolveTheme(theme);
188
+
189
+ return !type ? theme.bg.disabled : theme.button[type ?? 'light'].bg;
190
+ }};
191
+ flex-direction: row;
192
+ text-align: left;
193
+ align-items: center;
194
+ align-self: center;
195
+ position: absolute;
196
+ font-size: 16px;
197
+ padding: 10px 20px;
198
+ bottom: 20px;
199
+ border-radius: 20px;
200
+ `;