@umituz/react-native-design-system 2.6.61 → 2.6.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/atoms/AtomicButton.tsx +6 -257
- package/src/atoms/AtomicChip.tsx +4 -224
- package/src/atoms/AtomicIcon.tsx +2 -6
- package/src/atoms/AtomicIcon.types.ts +5 -0
- package/src/atoms/AtomicInput.tsx +34 -154
- package/src/atoms/AtomicPicker.tsx +31 -123
- package/src/atoms/button/AtomicButton.tsx +108 -0
- package/src/atoms/button/configs/buttonSizeConfig.ts +37 -0
- package/src/atoms/button/index.ts +6 -0
- package/src/atoms/button/styles/buttonStyles.ts +36 -0
- package/src/atoms/button/styles/buttonVariantStyles.ts +88 -0
- package/src/atoms/button/types/index.ts +40 -0
- package/src/atoms/chip/AtomicChip.tsx +112 -0
- package/src/atoms/chip/configs/chipColorConfig.ts +47 -0
- package/src/atoms/chip/configs/chipSizeConfig.ts +34 -0
- package/src/atoms/chip/index.ts +6 -0
- package/src/atoms/chip/styles/chipStyles.ts +28 -0
- package/src/atoms/chip/types/index.ts +42 -0
- package/src/atoms/index.ts +6 -4
- package/src/atoms/input/components/InputHelper.tsx +49 -0
- package/src/atoms/input/components/InputIcon.tsx +44 -0
- package/src/atoms/input/components/InputLabel.tsx +20 -0
- package/src/atoms/input/styles/inputStylesHelper.ts +1 -1
- package/src/atoms/input/types.ts +72 -0
- package/src/atoms/picker/hooks/usePickerState.ts +139 -0
- package/src/exports/atoms.ts +69 -0
- package/src/exports/device.ts +58 -0
- package/src/exports/layouts.ts +19 -0
- package/src/exports/molecules.ts +166 -0
- package/src/exports/organisms.ts +9 -0
- package/src/exports/responsive.ts +36 -0
- package/src/exports/safe-area.ts +6 -0
- package/src/exports/theme.ts +47 -0
- package/src/exports/typography.ts +22 -0
- package/src/exports/utilities.ts +6 -0
- package/src/exports/variants.ts +22 -0
- package/src/index.ts +11 -417
- package/src/layouts/ScreenLayout/ScreenLayout.tsx +17 -181
- package/src/layouts/ScreenLayout/components/ContentWrapper.tsx +31 -0
- package/src/layouts/ScreenLayout/components/index.ts +6 -0
- package/src/layouts/ScreenLayout/styles/screenLayoutStyles.ts +47 -0
- package/src/layouts/ScreenLayout/types/index.ts +27 -0
- package/src/molecules/avatar/Avatar.constants.ts +103 -0
- package/src/molecules/avatar/Avatar.types.ts +64 -0
- package/src/molecules/avatar/Avatar.utils.ts +8 -160
- package/src/molecules/calendar/index.ts +4 -9
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts +103 -302
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts.bak +116 -0
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.types.ts +64 -0
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.utils.ts +56 -0
- package/src/molecules/calendar/infrastructure/storage/EventActions.ts +140 -0
- package/src/molecules/calendar/infrastructure/storage/NavigationActions.ts +118 -0
- package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +34 -0
- package/src/molecules/calendar/infrastructure/stores/useCalendarEvents.ts +168 -0
- package/src/molecules/calendar/infrastructure/stores/useCalendarNavigation.ts +47 -0
- package/src/molecules/calendar/infrastructure/stores/useCalendarView.ts +24 -0
- package/src/molecules/calendar/presentation/hooks/useCalendar.ts +7 -11
- package/src/responsive/compute/computeDeviceInfo.ts +22 -0
- package/src/responsive/compute/computeResponsivePositioning.ts +42 -0
- package/src/responsive/compute/computeResponsiveSizes.ts +48 -0
- package/src/responsive/padding/paddingUtils.ts +65 -0
- package/src/responsive/positioning/positioningUtils.ts +61 -0
- package/src/responsive/responsiveLayout.ts +11 -264
- package/src/responsive/screen/screenLayoutConfig.ts +38 -0
- package/src/responsive/tabbar/tabBarConfig.ts +88 -0
- package/src/responsive/types/responsiveTypes.ts +69 -0
- package/src/responsive/useResponsive.ts +69 -158
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.64",
|
|
4
4
|
"description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive and safe area utilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -1,258 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { AtomicSpinner } from './AtomicSpinner';
|
|
6
|
-
import { useAppDesignTokens } from '../theme';
|
|
7
|
-
import type { IconName } from './AtomicIcon';
|
|
1
|
+
/**
|
|
2
|
+
* AtomicButton - Re-export from button module
|
|
3
|
+
* Maintains backward compatibility
|
|
4
|
+
*/
|
|
8
5
|
|
|
9
|
-
export
|
|
10
|
-
export type
|
|
11
|
-
|
|
12
|
-
export interface AtomicButtonProps {
|
|
13
|
-
title?: string;
|
|
14
|
-
children?: React.ReactNode;
|
|
15
|
-
onPress: () => void;
|
|
16
|
-
variant?: ButtonVariant;
|
|
17
|
-
size?: ButtonSize;
|
|
18
|
-
disabled?: boolean;
|
|
19
|
-
loading?: boolean;
|
|
20
|
-
icon?: IconName;
|
|
21
|
-
iconPosition?: 'left' | 'right';
|
|
22
|
-
fullWidth?: boolean;
|
|
23
|
-
style?: StyleProp<ViewStyle>;
|
|
24
|
-
textStyle?: StyleProp<TextStyle>;
|
|
25
|
-
activeOpacity?: number;
|
|
26
|
-
testID?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const AtomicButton: React.FC<AtomicButtonProps> = React.memo(({
|
|
30
|
-
title,
|
|
31
|
-
children,
|
|
32
|
-
onPress,
|
|
33
|
-
variant = 'primary',
|
|
34
|
-
size = 'md',
|
|
35
|
-
disabled = false,
|
|
36
|
-
loading = false,
|
|
37
|
-
icon,
|
|
38
|
-
iconPosition = 'left',
|
|
39
|
-
fullWidth = false,
|
|
40
|
-
style,
|
|
41
|
-
textStyle,
|
|
42
|
-
activeOpacity = 0.8,
|
|
43
|
-
testID,
|
|
44
|
-
}) => {
|
|
45
|
-
const tokens = useAppDesignTokens();
|
|
46
|
-
|
|
47
|
-
const handlePress = () => {
|
|
48
|
-
if (!disabled && !loading) {
|
|
49
|
-
onPress();
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const isDisabled = disabled || loading;
|
|
54
|
-
|
|
55
|
-
// Size configurations
|
|
56
|
-
const sizeConfig = {
|
|
57
|
-
sm: {
|
|
58
|
-
paddingVertical: tokens.spacing.xs,
|
|
59
|
-
paddingHorizontal: tokens.spacing.sm,
|
|
60
|
-
fontSize: tokens.typography.bodySmall.responsiveFontSize,
|
|
61
|
-
iconSize: 16 * tokens.spacingMultiplier,
|
|
62
|
-
minHeight: 32 * tokens.spacingMultiplier,
|
|
63
|
-
},
|
|
64
|
-
md: {
|
|
65
|
-
paddingVertical: tokens.spacing.sm,
|
|
66
|
-
paddingHorizontal: tokens.spacing.md,
|
|
67
|
-
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
68
|
-
iconSize: 20 * tokens.spacingMultiplier,
|
|
69
|
-
minHeight: 44 * tokens.spacingMultiplier,
|
|
70
|
-
},
|
|
71
|
-
lg: {
|
|
72
|
-
paddingVertical: tokens.spacing.md,
|
|
73
|
-
paddingHorizontal: tokens.spacing.lg,
|
|
74
|
-
fontSize: tokens.typography.bodyLarge.responsiveFontSize,
|
|
75
|
-
iconSize: 24 * tokens.spacingMultiplier,
|
|
76
|
-
minHeight: 52 * tokens.spacingMultiplier,
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const config = sizeConfig[size];
|
|
81
|
-
|
|
82
|
-
// Variant styles
|
|
83
|
-
const getVariantStyles = () => {
|
|
84
|
-
const baseStyle: ViewStyle = {
|
|
85
|
-
backgroundColor: tokens.colors.primary,
|
|
86
|
-
borderWidth: 0,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const baseTextStyle: TextStyle = {
|
|
90
|
-
color: tokens.colors.textInverse,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
switch (variant) {
|
|
94
|
-
case 'primary':
|
|
95
|
-
return {
|
|
96
|
-
container: {
|
|
97
|
-
...baseStyle,
|
|
98
|
-
backgroundColor: tokens.colors.primary,
|
|
99
|
-
},
|
|
100
|
-
text: {
|
|
101
|
-
...baseTextStyle,
|
|
102
|
-
color: tokens.colors.textInverse,
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
case 'secondary':
|
|
107
|
-
return {
|
|
108
|
-
container: {
|
|
109
|
-
...baseStyle,
|
|
110
|
-
backgroundColor: tokens.colors.surfaceSecondary,
|
|
111
|
-
},
|
|
112
|
-
text: {
|
|
113
|
-
...baseTextStyle,
|
|
114
|
-
color: tokens.colors.textPrimary,
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
case 'outline':
|
|
119
|
-
return {
|
|
120
|
-
container: {
|
|
121
|
-
...baseStyle,
|
|
122
|
-
backgroundColor: undefined,
|
|
123
|
-
borderWidth: 1,
|
|
124
|
-
borderColor: tokens.colors.border,
|
|
125
|
-
},
|
|
126
|
-
text: {
|
|
127
|
-
...baseTextStyle,
|
|
128
|
-
color: tokens.colors.textPrimary,
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
case 'text':
|
|
133
|
-
return {
|
|
134
|
-
container: {
|
|
135
|
-
...baseStyle,
|
|
136
|
-
backgroundColor: undefined,
|
|
137
|
-
},
|
|
138
|
-
text: {
|
|
139
|
-
...baseTextStyle,
|
|
140
|
-
color: tokens.colors.primary,
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
case 'danger':
|
|
145
|
-
return {
|
|
146
|
-
container: {
|
|
147
|
-
...baseStyle,
|
|
148
|
-
backgroundColor: tokens.colors.error,
|
|
149
|
-
},
|
|
150
|
-
text: {
|
|
151
|
-
...baseTextStyle,
|
|
152
|
-
color: tokens.colors.textInverse,
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
default:
|
|
157
|
-
return {
|
|
158
|
-
container: baseStyle,
|
|
159
|
-
text: baseTextStyle,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
const variantStyles = getVariantStyles();
|
|
165
|
-
|
|
166
|
-
const containerStyle: StyleProp<ViewStyle> = [
|
|
167
|
-
styles.button,
|
|
168
|
-
{
|
|
169
|
-
paddingVertical: config.paddingVertical,
|
|
170
|
-
paddingHorizontal: config.paddingHorizontal,
|
|
171
|
-
minHeight: config.minHeight,
|
|
172
|
-
borderRadius: tokens.borders.radius.md,
|
|
173
|
-
},
|
|
174
|
-
variantStyles.container,
|
|
175
|
-
fullWidth ? styles.fullWidth : undefined,
|
|
176
|
-
isDisabled ? styles.disabled : undefined,
|
|
177
|
-
style,
|
|
178
|
-
];
|
|
179
|
-
|
|
180
|
-
const buttonTextStyle: StyleProp<TextStyle> = [
|
|
181
|
-
{
|
|
182
|
-
fontSize: config.fontSize,
|
|
183
|
-
fontWeight: '600',
|
|
184
|
-
},
|
|
185
|
-
variantStyles.text,
|
|
186
|
-
isDisabled ? styles.disabledText : undefined,
|
|
187
|
-
textStyle,
|
|
188
|
-
];
|
|
189
|
-
|
|
190
|
-
const buttonText = title || children;
|
|
191
|
-
const showIcon = icon;
|
|
192
|
-
const iconColor = variantStyles.text.color;
|
|
193
|
-
|
|
194
|
-
return (
|
|
195
|
-
<TouchableOpacity
|
|
196
|
-
style={containerStyle}
|
|
197
|
-
onPress={handlePress}
|
|
198
|
-
activeOpacity={activeOpacity}
|
|
199
|
-
disabled={isDisabled}
|
|
200
|
-
testID={testID}
|
|
201
|
-
>
|
|
202
|
-
<View style={[styles.content, iconPosition === 'right' && styles.rowReverse]}>
|
|
203
|
-
{loading ? (
|
|
204
|
-
<AtomicSpinner
|
|
205
|
-
size="sm"
|
|
206
|
-
color={iconColor as string}
|
|
207
|
-
style={iconPosition === 'right' ? styles.iconRight : styles.iconLeft}
|
|
208
|
-
/>
|
|
209
|
-
) : showIcon ? (
|
|
210
|
-
<AtomicIcon
|
|
211
|
-
name={icon}
|
|
212
|
-
customSize={config.iconSize}
|
|
213
|
-
customColor={iconColor as string | undefined}
|
|
214
|
-
style={iconPosition === 'right' ? styles.iconRight : styles.iconLeft}
|
|
215
|
-
/>
|
|
216
|
-
) : null}
|
|
217
|
-
|
|
218
|
-
<AtomicText style={buttonTextStyle}>
|
|
219
|
-
{buttonText}
|
|
220
|
-
</AtomicText>
|
|
221
|
-
</View>
|
|
222
|
-
</TouchableOpacity>
|
|
223
|
-
);
|
|
224
|
-
});
|
|
225
|
-
AtomicButton.displayName = 'AtomicButton';
|
|
226
|
-
|
|
227
|
-
const styles = StyleSheet.create({
|
|
228
|
-
button: {
|
|
229
|
-
alignItems: 'center',
|
|
230
|
-
justifyContent: 'center',
|
|
231
|
-
flexDirection: 'row',
|
|
232
|
-
},
|
|
233
|
-
content: {
|
|
234
|
-
flexDirection: 'row',
|
|
235
|
-
alignItems: 'center',
|
|
236
|
-
justifyContent: 'center',
|
|
237
|
-
},
|
|
238
|
-
rowReverse: {
|
|
239
|
-
flexDirection: 'row-reverse',
|
|
240
|
-
},
|
|
241
|
-
fullWidth: {
|
|
242
|
-
width: '100%',
|
|
243
|
-
},
|
|
244
|
-
disabled: {
|
|
245
|
-
opacity: 0.5,
|
|
246
|
-
},
|
|
247
|
-
disabledText: {
|
|
248
|
-
opacity: 0.7,
|
|
249
|
-
},
|
|
250
|
-
iconLeft: {
|
|
251
|
-
marginRight: 8,
|
|
252
|
-
},
|
|
253
|
-
iconRight: {
|
|
254
|
-
marginLeft: 8,
|
|
255
|
-
},
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
export type { AtomicButtonProps as ButtonProps };
|
|
6
|
+
export { AtomicButton } from './button';
|
|
7
|
+
export type { AtomicButtonProps, ButtonVariant, ButtonSize } from './button';
|
package/src/atoms/AtomicChip.tsx
CHANGED
|
@@ -1,227 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AtomicChip -
|
|
3
|
-
*
|
|
4
|
-
* Displays small tags, labels, or status indicators
|
|
5
|
-
* Theme: {{THEME_NAME}} ({{CATEGORY}} category)
|
|
6
|
-
*
|
|
7
|
-
* Atomic Design Level: ATOM
|
|
8
|
-
* Purpose: Tag and label display
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* - Category tags
|
|
12
|
-
* - Status indicators
|
|
13
|
-
* - Filter chips
|
|
14
|
-
* - Skill labels
|
|
15
|
-
* - Badge displays
|
|
2
|
+
* AtomicChip - Re-export from chip module
|
|
3
|
+
* Maintains backward compatibility
|
|
16
4
|
*/
|
|
17
5
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import { AtomicText } from './AtomicText';
|
|
21
|
-
import { AtomicIcon } from './AtomicIcon';
|
|
22
|
-
import { useAppDesignTokens } from '../theme';
|
|
23
|
-
|
|
24
|
-
// =============================================================================
|
|
25
|
-
// TYPE DEFINITIONS
|
|
26
|
-
// =============================================================================
|
|
27
|
-
|
|
28
|
-
export interface AtomicChipProps {
|
|
29
|
-
/** Text content of the chip */
|
|
30
|
-
children: React.ReactNode;
|
|
31
|
-
/** Chip variant */
|
|
32
|
-
variant?: 'filled' | 'outlined' | 'soft';
|
|
33
|
-
/** Chip size */
|
|
34
|
-
size?: 'sm' | 'md' | 'lg';
|
|
35
|
-
/** Chip color theme */
|
|
36
|
-
color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
|
|
37
|
-
/** Custom background color */
|
|
38
|
-
backgroundColor?: string;
|
|
39
|
-
/** Custom text color */
|
|
40
|
-
textColor?: string;
|
|
41
|
-
/** Custom border color */
|
|
42
|
-
borderColor?: string;
|
|
43
|
-
/** Leading icon */
|
|
44
|
-
leadingIcon?: string;
|
|
45
|
-
/** Trailing icon */
|
|
46
|
-
trailingIcon?: string;
|
|
47
|
-
/** Whether the chip is clickable */
|
|
48
|
-
clickable?: boolean;
|
|
49
|
-
/** Click handler */
|
|
50
|
-
onPress?: () => void;
|
|
51
|
-
/** Whether the chip is selected */
|
|
52
|
-
selected?: boolean;
|
|
53
|
-
/** Whether the chip is disabled */
|
|
54
|
-
disabled?: boolean;
|
|
55
|
-
/** Style overrides */
|
|
56
|
-
style?: ViewStyle;
|
|
57
|
-
/** Test ID for testing */
|
|
58
|
-
testID?: string;
|
|
59
|
-
/** Active opacity for touch feedback */
|
|
60
|
-
activeOpacity?: number;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// =============================================================================
|
|
64
|
-
// COMPONENT IMPLEMENTATION
|
|
65
|
-
// =============================================================================
|
|
66
|
-
|
|
67
|
-
export const AtomicChip: React.FC<AtomicChipProps> = React.memo(({
|
|
68
|
-
children,
|
|
69
|
-
variant = 'filled',
|
|
70
|
-
size = 'md',
|
|
71
|
-
color = 'primary',
|
|
72
|
-
backgroundColor,
|
|
73
|
-
textColor,
|
|
74
|
-
borderColor,
|
|
75
|
-
leadingIcon,
|
|
76
|
-
trailingIcon,
|
|
77
|
-
clickable = false,
|
|
78
|
-
onPress,
|
|
79
|
-
selected = false,
|
|
80
|
-
disabled = false,
|
|
81
|
-
style,
|
|
82
|
-
testID,
|
|
83
|
-
activeOpacity = 0.7,
|
|
84
|
-
}) => {
|
|
85
|
-
const tokens = useAppDesignTokens();
|
|
86
|
-
|
|
87
|
-
// Size mapping
|
|
88
|
-
const sizeMap = {
|
|
89
|
-
sm: {
|
|
90
|
-
paddingHorizontal: tokens.spacing.sm,
|
|
91
|
-
paddingVertical: tokens.spacing.xs,
|
|
92
|
-
fontSize: tokens.typography.bodySmall.responsiveFontSize,
|
|
93
|
-
iconSize: 'xs' as const
|
|
94
|
-
},
|
|
95
|
-
md: {
|
|
96
|
-
paddingHorizontal: tokens.spacing.md,
|
|
97
|
-
paddingVertical: tokens.spacing.sm,
|
|
98
|
-
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
99
|
-
iconSize: 'sm' as const
|
|
100
|
-
},
|
|
101
|
-
lg: {
|
|
102
|
-
paddingHorizontal: tokens.spacing.md,
|
|
103
|
-
paddingVertical: tokens.spacing.sm,
|
|
104
|
-
fontSize: tokens.typography.bodyLarge.responsiveFontSize,
|
|
105
|
-
iconSize: 'sm' as const
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const sizeConfig = sizeMap[size];
|
|
110
|
-
|
|
111
|
-
// Color mapping - using undefined for transparent backgrounds
|
|
112
|
-
const colorMap = {
|
|
113
|
-
primary: {
|
|
114
|
-
filled: { bg: tokens.colors.primary, text: tokens.colors.onPrimary, border: tokens.colors.primary },
|
|
115
|
-
outlined: { bg: undefined, text: tokens.colors.primary, border: tokens.colors.primary },
|
|
116
|
-
soft: { bg: tokens.colors.primaryContainer, text: tokens.colors.onPrimaryContainer, border: undefined },
|
|
117
|
-
},
|
|
118
|
-
secondary: {
|
|
119
|
-
filled: { bg: tokens.colors.secondary, text: tokens.colors.onSecondary, border: tokens.colors.secondary },
|
|
120
|
-
outlined: { bg: undefined, text: tokens.colors.secondary, border: tokens.colors.secondary },
|
|
121
|
-
soft: { bg: tokens.colors.secondaryContainer, text: tokens.colors.onSecondaryContainer, border: undefined },
|
|
122
|
-
},
|
|
123
|
-
success: {
|
|
124
|
-
filled: { bg: tokens.colors.success, text: tokens.colors.onSuccess, border: tokens.colors.success },
|
|
125
|
-
outlined: { bg: undefined, text: tokens.colors.success, border: tokens.colors.success },
|
|
126
|
-
soft: { bg: tokens.colors.successContainer, text: tokens.colors.onSuccessContainer, border: undefined },
|
|
127
|
-
},
|
|
128
|
-
warning: {
|
|
129
|
-
filled: { bg: tokens.colors.warning, text: tokens.colors.onWarning, border: tokens.colors.warning },
|
|
130
|
-
outlined: { bg: undefined, text: tokens.colors.warning, border: tokens.colors.warning },
|
|
131
|
-
soft: { bg: tokens.colors.warningContainer, text: tokens.colors.onWarningContainer, border: undefined },
|
|
132
|
-
},
|
|
133
|
-
error: {
|
|
134
|
-
filled: { bg: tokens.colors.error, text: tokens.colors.onError, border: tokens.colors.error },
|
|
135
|
-
outlined: { bg: undefined, text: tokens.colors.error, border: tokens.colors.error },
|
|
136
|
-
soft: { bg: tokens.colors.errorContainer, text: tokens.colors.onErrorContainer, border: undefined },
|
|
137
|
-
},
|
|
138
|
-
info: {
|
|
139
|
-
filled: { bg: tokens.colors.info, text: tokens.colors.onInfo, border: tokens.colors.info },
|
|
140
|
-
outlined: { bg: undefined, text: tokens.colors.info, border: tokens.colors.info },
|
|
141
|
-
soft: { bg: tokens.colors.infoContainer, text: tokens.colors.onInfoContainer, border: undefined },
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const colorConfig = colorMap[color][variant];
|
|
146
|
-
|
|
147
|
-
// Apply custom colors if provided
|
|
148
|
-
const finalBackgroundColor = backgroundColor || colorConfig.bg;
|
|
149
|
-
const finalTextColor = textColor || colorConfig.text;
|
|
150
|
-
const finalBorderColor = borderColor || colorConfig.border;
|
|
151
|
-
|
|
152
|
-
// Handle disabled state
|
|
153
|
-
const isDisabled = disabled || (!clickable && !onPress);
|
|
154
|
-
const opacity = isDisabled ? 0.5 : 1;
|
|
155
|
-
|
|
156
|
-
// Handle selected state
|
|
157
|
-
const selectedStyle = selected ? {
|
|
158
|
-
borderWidth: tokens.borders.width.medium,
|
|
159
|
-
borderColor: tokens.colors.primary,
|
|
160
|
-
} : {};
|
|
161
|
-
|
|
162
|
-
const chipStyle: ViewStyle = {
|
|
163
|
-
flexDirection: 'row',
|
|
164
|
-
alignItems: 'center',
|
|
165
|
-
justifyContent: 'center',
|
|
166
|
-
paddingHorizontal: sizeConfig.paddingHorizontal,
|
|
167
|
-
paddingVertical: sizeConfig.paddingVertical,
|
|
168
|
-
backgroundColor: finalBackgroundColor,
|
|
169
|
-
borderRadius: tokens.borders.radius.xl,
|
|
170
|
-
borderWidth: variant === 'outlined' ? 1 : 0,
|
|
171
|
-
borderColor: finalBorderColor,
|
|
172
|
-
opacity,
|
|
173
|
-
...selectedStyle,
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const textStyle = {
|
|
177
|
-
fontSize: sizeConfig.fontSize,
|
|
178
|
-
fontWeight: tokens.typography.medium,
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const iconColor = finalTextColor;
|
|
182
|
-
|
|
183
|
-
const content = (
|
|
184
|
-
<View style={[chipStyle, style]} testID={testID}>
|
|
185
|
-
{leadingIcon && (
|
|
186
|
-
<AtomicIcon
|
|
187
|
-
name={leadingIcon}
|
|
188
|
-
size={sizeConfig.iconSize}
|
|
189
|
-
customColor={iconColor}
|
|
190
|
-
style={{ marginRight: tokens.spacing.xs }}
|
|
191
|
-
/>
|
|
192
|
-
)}
|
|
193
|
-
<AtomicText
|
|
194
|
-
type="labelMedium"
|
|
195
|
-
color={finalTextColor}
|
|
196
|
-
style={textStyle}
|
|
197
|
-
>
|
|
198
|
-
{children}
|
|
199
|
-
</AtomicText>
|
|
200
|
-
{trailingIcon && (
|
|
201
|
-
<AtomicIcon
|
|
202
|
-
name={trailingIcon}
|
|
203
|
-
size={sizeConfig.iconSize}
|
|
204
|
-
customColor={iconColor}
|
|
205
|
-
style={{ marginLeft: tokens.spacing.xs }}
|
|
206
|
-
/>
|
|
207
|
-
)}
|
|
208
|
-
</View>
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
if (clickable && onPress && !disabled) {
|
|
212
|
-
return (
|
|
213
|
-
<TouchableOpacity onPress={onPress} activeOpacity={activeOpacity}>
|
|
214
|
-
{content}
|
|
215
|
-
</TouchableOpacity>
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return content;
|
|
220
|
-
});
|
|
221
|
-
AtomicChip.displayName = 'AtomicChip';
|
|
222
|
-
|
|
223
|
-
// =============================================================================
|
|
224
|
-
// EXPORTS
|
|
225
|
-
// =============================================================================
|
|
226
|
-
|
|
227
|
-
export default AtomicChip;
|
|
6
|
+
export { AtomicChip } from './chip';
|
|
7
|
+
export type { AtomicChipProps } from './chip';
|
package/src/atoms/AtomicIcon.tsx
CHANGED
|
@@ -12,11 +12,12 @@ import Svg, { Path } from "react-native-svg";
|
|
|
12
12
|
import { useAppDesignTokens } from '../theme';
|
|
13
13
|
import {
|
|
14
14
|
type IconSize as BaseIconSize,
|
|
15
|
-
type
|
|
15
|
+
type IconName,
|
|
16
16
|
} from "./AtomicIcon.types";
|
|
17
17
|
|
|
18
18
|
// Re-export IconSize for convenience
|
|
19
19
|
export type IconSize = BaseIconSize;
|
|
20
|
+
export type { IconName };
|
|
20
21
|
|
|
21
22
|
const FALLBACK_ICON = "help-circle-outline";
|
|
22
23
|
|
|
@@ -38,11 +39,6 @@ export type IconColor =
|
|
|
38
39
|
| "textTertiary"
|
|
39
40
|
| "onSurfaceVariant";
|
|
40
41
|
|
|
41
|
-
/**
|
|
42
|
-
* IconName can be a valid Ionicons name or any string (for custom SVGs)
|
|
43
|
-
*/
|
|
44
|
-
export type IconName = IoniconsName | string;
|
|
45
|
-
|
|
46
42
|
export interface AtomicIconProps {
|
|
47
43
|
/** Icon name (Ionicons) */
|
|
48
44
|
name?: IconName;
|
|
@@ -10,6 +10,11 @@ import type { Ionicons } from "@expo/vector-icons";
|
|
|
10
10
|
*/
|
|
11
11
|
export type IoniconsName = keyof typeof Ionicons.glyphMap;
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Icon name - either Ionicons or custom string
|
|
15
|
+
*/
|
|
16
|
+
export type IconName = IoniconsName | string;
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* Semantic icon size presets
|
|
15
20
|
*/
|