@umituz/react-native-design-system 1.5.36 → 1.5.38

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 (62) hide show
  1. package/README.md +2 -2
  2. package/package.json +7 -5
  3. package/src/index.ts +29 -221
  4. package/src/presentation/organisms/AppHeader.tsx +3 -5
  5. package/src/presentation/tokens/commonStyles.ts +1 -1
  6. package/src/presentation/atoms/AtomicAvatar.tsx +0 -157
  7. package/src/presentation/atoms/AtomicAvatarGroup.tsx +0 -169
  8. package/src/presentation/atoms/AtomicBadge.tsx +0 -232
  9. package/src/presentation/atoms/AtomicButton.tsx +0 -236
  10. package/src/presentation/atoms/AtomicCard.tsx +0 -107
  11. package/src/presentation/atoms/AtomicChip.tsx +0 -223
  12. package/src/presentation/atoms/AtomicDatePicker.tsx +0 -347
  13. package/src/presentation/atoms/AtomicDivider.tsx +0 -114
  14. package/src/presentation/atoms/AtomicFab.tsx +0 -98
  15. package/src/presentation/atoms/AtomicFilter.tsx +0 -154
  16. package/src/presentation/atoms/AtomicFormError.tsx +0 -105
  17. package/src/presentation/atoms/AtomicIcon.tsx +0 -40
  18. package/src/presentation/atoms/AtomicImage.tsx +0 -149
  19. package/src/presentation/atoms/AtomicInput.tsx +0 -363
  20. package/src/presentation/atoms/AtomicNumberInput.tsx +0 -182
  21. package/src/presentation/atoms/AtomicPicker.tsx +0 -458
  22. package/src/presentation/atoms/AtomicProgress.tsx +0 -139
  23. package/src/presentation/atoms/AtomicSearchBar.tsx +0 -114
  24. package/src/presentation/atoms/AtomicSort.tsx +0 -145
  25. package/src/presentation/atoms/AtomicSwitch.tsx +0 -166
  26. package/src/presentation/atoms/AtomicText.tsx +0 -55
  27. package/src/presentation/atoms/AtomicTextArea.tsx +0 -313
  28. package/src/presentation/atoms/AtomicTouchable.tsx +0 -209
  29. package/src/presentation/atoms/fab/styles/fabStyles.ts +0 -69
  30. package/src/presentation/atoms/fab/types/index.ts +0 -82
  31. package/src/presentation/atoms/filter/styles/filterStyles.ts +0 -32
  32. package/src/presentation/atoms/filter/types/index.ts +0 -89
  33. package/src/presentation/atoms/index.ts +0 -366
  34. package/src/presentation/atoms/input/hooks/useInputState.ts +0 -15
  35. package/src/presentation/atoms/input/styles/inputStyles.ts +0 -66
  36. package/src/presentation/atoms/input/types/index.ts +0 -25
  37. package/src/presentation/atoms/picker/styles/pickerStyles.ts +0 -207
  38. package/src/presentation/atoms/picker/types/index.ts +0 -40
  39. package/src/presentation/atoms/touchable/styles/touchableStyles.ts +0 -62
  40. package/src/presentation/atoms/touchable/types/index.ts +0 -155
  41. package/src/presentation/hooks/useResponsive.ts +0 -180
  42. package/src/presentation/molecules/AtomicConfirmationModal.tsx +0 -243
  43. package/src/presentation/molecules/EmptyState.tsx +0 -130
  44. package/src/presentation/molecules/FormField.tsx +0 -128
  45. package/src/presentation/molecules/GridContainer.tsx +0 -124
  46. package/src/presentation/molecules/IconContainer.tsx +0 -94
  47. package/src/presentation/molecules/ListItem.tsx +0 -36
  48. package/src/presentation/molecules/ScreenHeader.tsx +0 -140
  49. package/src/presentation/molecules/SearchBar.tsx +0 -85
  50. package/src/presentation/molecules/SectionCard.tsx +0 -74
  51. package/src/presentation/molecules/SectionContainer.tsx +0 -106
  52. package/src/presentation/molecules/SectionHeader.tsx +0 -125
  53. package/src/presentation/molecules/confirmation-modal/styles/confirmationModalStyles.ts +0 -133
  54. package/src/presentation/molecules/confirmation-modal/types/index.ts +0 -105
  55. package/src/presentation/molecules/index.ts +0 -41
  56. package/src/presentation/molecules/listitem/styles/listItemStyles.ts +0 -19
  57. package/src/presentation/molecules/listitem/types/index.ts +0 -17
  58. package/src/presentation/organisms/FormContainer.tsx +0 -180
  59. package/src/presentation/organisms/ScreenLayout.tsx +0 -171
  60. package/src/presentation/organisms/index.ts +0 -25
  61. package/src/presentation/utils/platformConstants.ts +0 -124
  62. package/src/presentation/utils/responsive.ts +0 -516
@@ -1,169 +0,0 @@
1
- /**
2
- * AtomicAvatarGroup - Universal Avatar Group Component
3
- *
4
- * Displays multiple avatars in a group with overlap and overflow handling
5
- * Theme: {{THEME_NAME}} ({{CATEGORY}} category)
6
- *
7
- * Atomic Design Level: ATOM
8
- * Purpose: Multiple avatar display with group behavior
9
- *
10
- * Usage:
11
- * - Team member avatars
12
- * - Group chat participants
13
- * - Project collaborators
14
- * - Event attendees
15
- * - Social connections
16
- */
17
-
18
- import React from 'react';
19
- import { View, StyleSheet, ViewStyle } from 'react-native';
20
- import { AtomicAvatar, AtomicAvatarProps } from './AtomicAvatar';
21
- import { AtomicText } from './AtomicText';
22
- import { useAppDesignTokens } from '@umituz/react-native-theme';
23
-
24
- // =============================================================================
25
- // TYPE DEFINITIONS
26
- // =============================================================================
27
-
28
- export interface AvatarData {
29
- id: string;
30
- source?: { uri: string } | number;
31
- name?: string;
32
- backgroundColor?: string;
33
- textColor?: string;
34
- }
35
-
36
- export interface AtomicAvatarGroupProps {
37
- /** Array of avatar data */
38
- avatars: AvatarData[];
39
- /** Maximum number of avatars to show */
40
- maxVisible?: number;
41
- /** Avatar size */
42
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
43
- /** Custom avatar size */
44
- customSize?: number;
45
- /** Spacing between avatars */
46
- spacing?: number;
47
- /** Whether to show overflow count */
48
- showOverflow?: boolean;
49
- /** Overflow count background color */
50
- overflowBackgroundColor?: string;
51
- /** Overflow count text color */
52
- overflowTextColor?: string;
53
- /** Avatar border width */
54
- borderWidth?: number;
55
- /** Avatar border color */
56
- borderColor?: string;
57
- /** Style overrides */
58
- style?: ViewStyle;
59
- /** Test ID for testing */
60
- testID?: string;
61
- }
62
-
63
- // =============================================================================
64
- // COMPONENT IMPLEMENTATION
65
- // =============================================================================
66
-
67
- export const AtomicAvatarGroup: React.FC<AtomicAvatarGroupProps> = ({
68
- avatars,
69
- maxVisible = 3,
70
- size = 'md',
71
- customSize,
72
- spacing = -8,
73
- showOverflow = true,
74
- overflowBackgroundColor,
75
- overflowTextColor,
76
- borderWidth = 2,
77
- borderColor,
78
- style,
79
- testID,
80
- }) => {
81
- const tokens = useAppDesignTokens();
82
-
83
- // Calculate visible avatars and overflow count
84
- const visibleAvatars = avatars.slice(0, maxVisible);
85
- const overflowCount = avatars.length - maxVisible;
86
-
87
- // Size mapping for overflow text
88
- const sizeMap = {
89
- xs: 10,
90
- sm: 12,
91
- md: 14,
92
- lg: 16,
93
- xl: 18,
94
- xxl: 20,
95
- };
96
-
97
- const textSize = sizeMap[size];
98
-
99
- // Default colors for overflow
100
- const defaultOverflowBackground = overflowBackgroundColor || tokens.colors.surfaceVariant;
101
- const defaultOverflowText = overflowTextColor || tokens.colors.textPrimary;
102
-
103
- const containerStyle: ViewStyle = {
104
- flexDirection: 'row',
105
- alignItems: 'center',
106
- };
107
-
108
- const avatarStyle: ViewStyle = {
109
- marginLeft: spacing,
110
- borderWidth,
111
- borderColor: borderColor || tokens.colors.surface,
112
- };
113
-
114
- return (
115
- <View style={[containerStyle, style]} testID={testID}>
116
- {visibleAvatars.map((avatar, index) => (
117
- <AtomicAvatar
118
- key={avatar.id}
119
- source={avatar.source}
120
- name={avatar.name}
121
- size={size}
122
- customSize={customSize}
123
- backgroundColor={avatar.backgroundColor}
124
- textColor={avatar.textColor}
125
- borderWidth={borderWidth}
126
- borderColor={borderColor}
127
- style={[
128
- avatarStyle,
129
- ...(index === 0 ? [{ marginLeft: 0 }] : []), // First avatar has no left margin
130
- ]}
131
- />
132
- ))}
133
- {showOverflow && overflowCount > 0 && (
134
- <View
135
- style={[
136
- {
137
- alignItems: 'center',
138
- justifyContent: 'center',
139
- width: customSize || 40,
140
- height: customSize || 40,
141
- borderRadius: (customSize || 40) / 2,
142
- backgroundColor: defaultOverflowBackground,
143
- borderWidth,
144
- borderColor: borderColor || tokens.colors.surface,
145
- marginLeft: spacing,
146
- },
147
- ]}
148
- >
149
- <AtomicText
150
- type="labelMedium"
151
- color={defaultOverflowText}
152
- style={{
153
- fontWeight: tokens.typography.semibold,
154
- fontSize: textSize,
155
- }}
156
- >
157
- +{overflowCount}
158
- </AtomicText>
159
- </View>
160
- )}
161
- </View>
162
- );
163
- };
164
-
165
- // =============================================================================
166
- // EXPORTS
167
- // =============================================================================
168
-
169
- export default AtomicAvatarGroup;
@@ -1,232 +0,0 @@
1
- /**
2
- * AtomicBadge - Universal Badge Component
3
- *
4
- * Provides consistent badge/notification count display
5
- * Theme: {{THEME_NAME}} ({{CATEGORY}} category)
6
- *
7
- * Atomic Design Level: ATOM
8
- * Purpose: Display counts, notifications, status indicators
9
- *
10
- * Usage:
11
- * - Notification counts
12
- * - Cart item counts
13
- * - Status indicators
14
- * - Achievement badges
15
- */
16
-
17
- import React from 'react';
18
- import { View, StyleSheet, StyleProp, ViewStyle, TextStyle } from 'react-native';
19
- import { AtomicText } from './AtomicText';
20
- import { useAppDesignTokens } from '@umituz/react-native-theme';
21
- import type { DesignTokens } from '@umituz/react-native-theme';
22
-
23
- // =============================================================================
24
- // TYPE DEFINITIONS
25
- // =============================================================================
26
-
27
- export interface AtomicBadgeProps {
28
- /** Badge content (number, text, or custom element) */
29
- children: React.ReactNode;
30
- /** Size variant */
31
- size?: 'xs' | 'sm' | 'md' | 'lg';
32
- /** Color variant */
33
- variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
34
- /** Shape variant */
35
- shape?: 'circle' | 'rounded' | 'square';
36
- /** Maximum value to display (e.g., 99+) */
37
- max?: number;
38
- /** Show badge even when count is 0 */
39
- showZero?: boolean;
40
- /** Container style override */
41
- style?: StyleProp<ViewStyle>;
42
- /** Text style override */
43
- textStyle?: StyleProp<TextStyle>;
44
- /** Minimum width */
45
- minWidth?: number;
46
- /** Maximum width */
47
- maxWidth?: number;
48
- }
49
-
50
- // =============================================================================
51
- // SIZE CONFIGURATION
52
- // =============================================================================
53
-
54
- const getSizeConfig = (tokens: DesignTokens) => ({
55
- xs: {
56
- minHeight: tokens.spacing.sm,
57
- paddingHorizontal: tokens.spacing.xs,
58
- fontSize: tokens.typography.labelSmall.fontSize,
59
- borderRadius: tokens.borders.radius.sm,
60
- },
61
- sm: {
62
- minHeight: tokens.spacing.md,
63
- paddingHorizontal: tokens.spacing.sm,
64
- fontSize: tokens.typography.bodySmall.fontSize,
65
- borderRadius: tokens.borders.radius.md,
66
- },
67
- md: {
68
- minHeight: tokens.spacing.lg,
69
- paddingHorizontal: tokens.spacing.sm,
70
- fontSize: tokens.typography.bodyMedium.fontSize,
71
- borderRadius: tokens.borders.radius.md,
72
- },
73
- lg: {
74
- minHeight: tokens.spacing.xl,
75
- paddingHorizontal: tokens.spacing.md,
76
- fontSize: tokens.typography.bodyLarge.fontSize,
77
- borderRadius: tokens.borders.radius.lg,
78
- },
79
- });
80
-
81
- // =============================================================================
82
- // COMPONENT IMPLEMENTATION
83
- // =============================================================================
84
-
85
- export const AtomicBadge: React.FC<AtomicBadgeProps> = ({
86
- children,
87
- size = 'md',
88
- variant = 'primary',
89
- shape = 'circle',
90
- max,
91
- showZero = false,
92
- style,
93
- textStyle,
94
- minWidth,
95
- maxWidth,
96
- }) => {
97
- const tokens = useAppDesignTokens();
98
- const styles = getStyles(tokens);
99
-
100
- const sizeConfig = getSizeConfig(tokens)[size as 'xs' | 'sm' | 'md' | 'lg'];
101
- const colors = getVariantColors(tokens, variant as 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info');
102
- const borderRadius = getBorderRadius(shape as 'circle' | 'rounded' | 'square', sizeConfig.borderRadius, tokens);
103
-
104
- // Handle max value display
105
- const displayValue = React.useMemo(() => {
106
- if (typeof children === 'number') {
107
- if (max && children > max) {
108
- return `${max}+`;
109
- }
110
- return children.toString();
111
- }
112
- return children;
113
- }, [children, max]);
114
-
115
- // Don't render if count is 0 and showZero is false
116
- if (typeof children === 'number' && children === 0 && !showZero) {
117
- return null;
118
- }
119
-
120
- const containerStyle = [
121
- styles.container,
122
- {
123
- minHeight: sizeConfig.minHeight,
124
- paddingHorizontal: sizeConfig.paddingHorizontal,
125
- borderRadius,
126
- backgroundColor: colors.background,
127
- minWidth: minWidth || sizeConfig.minHeight,
128
- maxWidth,
129
- },
130
- style,
131
- ];
132
-
133
- const textStyleFinal = StyleSheet.flatten([
134
- styles.text,
135
- {
136
- fontSize: sizeConfig.fontSize,
137
- },
138
- textStyle,
139
- ]);
140
-
141
- return (
142
- <View style={containerStyle}>
143
- <AtomicText
144
- type="bodySmall"
145
- color={colors.text}
146
- style={textStyleFinal}
147
- numberOfLines={1}
148
- >
149
- {displayValue}
150
- </AtomicText>
151
- </View>
152
- );
153
- };
154
-
155
- // =============================================================================
156
- // HELPER FUNCTIONS
157
- // =============================================================================
158
-
159
- const getVariantColors = (tokens: ReturnType<typeof useAppDesignTokens>, variant: AtomicBadgeProps['variant']) => {
160
- switch (variant) {
161
- case 'primary':
162
- return {
163
- background: tokens.colors.primary,
164
- text: tokens.colors.textInverse,
165
- };
166
- case 'secondary':
167
- return {
168
- background: tokens.colors.secondary,
169
- text: tokens.colors.textInverse,
170
- };
171
- case 'success':
172
- return {
173
- background: tokens.colors.success,
174
- text: tokens.colors.textInverse,
175
- };
176
- case 'warning':
177
- return {
178
- background: tokens.colors.warning,
179
- text: tokens.colors.textInverse,
180
- };
181
- case 'error':
182
- return {
183
- background: tokens.colors.error,
184
- text: tokens.colors.textInverse,
185
- };
186
- case 'info':
187
- return {
188
- background: tokens.colors.info,
189
- text: tokens.colors.textInverse,
190
- };
191
- default:
192
- return {
193
- background: tokens.colors.primary,
194
- text: tokens.colors.textInverse,
195
- };
196
- }
197
- };
198
-
199
- const getBorderRadius = (shape: AtomicBadgeProps['shape'], defaultRadius: number, tokens: ReturnType<typeof useAppDesignTokens>): number => {
200
- switch (shape) {
201
- case 'circle':
202
- return tokens.borders.radius.full; // Very large radius for circle
203
- case 'square':
204
- return tokens.borders.radius.sm;
205
- case 'rounded':
206
- default:
207
- return defaultRadius;
208
- }
209
- };
210
-
211
- // =============================================================================
212
- // STYLES
213
- // =============================================================================
214
-
215
- const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
216
- StyleSheet.create({
217
- container: {
218
- justifyContent: 'center',
219
- alignItems: 'center',
220
- alignSelf: 'flex-start',
221
- },
222
- text: {
223
- fontWeight: tokens.typography.semibold,
224
- textAlign: 'center',
225
- },
226
- });
227
-
228
- // =============================================================================
229
- // EXPORTS
230
- // =============================================================================
231
-
232
- export default AtomicBadge;
@@ -1,236 +0,0 @@
1
- import React from 'react';
2
- import { StyleSheet, StyleProp, ViewStyle, TextStyle, TouchableOpacity, View } from 'react-native';
3
- import { AtomicText } from './AtomicText';
4
- import { Icon } from '@umituz/react-native-icon';
5
- import { useAppDesignTokens } from '@umituz/react-native-theme';
6
- import type { IconName } from '@umituz/react-native-icon';
7
-
8
- export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'text' | 'danger';
9
- export type ButtonSize = 'sm' | 'md' | 'lg';
10
-
11
- export interface AtomicButtonProps {
12
- title?: string;
13
- children?: React.ReactNode;
14
- onPress: () => void;
15
- variant?: ButtonVariant;
16
- size?: ButtonSize;
17
- disabled?: boolean;
18
- icon?: IconName;
19
- fullWidth?: boolean;
20
- style?: StyleProp<ViewStyle>;
21
- textStyle?: StyleProp<TextStyle>;
22
- testID?: string;
23
- }
24
-
25
- export const AtomicButton: React.FC<AtomicButtonProps> = ({
26
- title,
27
- children,
28
- onPress,
29
- variant = 'primary',
30
- size = 'md',
31
- disabled = false,
32
- icon,
33
- fullWidth = false,
34
- style,
35
- textStyle,
36
- testID,
37
- }) => {
38
- const tokens = useAppDesignTokens();
39
-
40
- const handlePress = () => {
41
- if (!disabled) {
42
- onPress();
43
- }
44
- };
45
-
46
- // Size configurations
47
- const sizeConfig = {
48
- sm: {
49
- paddingVertical: tokens.spacing.xs,
50
- paddingHorizontal: tokens.spacing.sm,
51
- fontSize: tokens.typography.bodySmall.fontSize,
52
- iconSize: 16,
53
- minHeight: 32,
54
- },
55
- md: {
56
- paddingVertical: tokens.spacing.sm,
57
- paddingHorizontal: tokens.spacing.md,
58
- fontSize: tokens.typography.bodyMedium.fontSize,
59
- iconSize: 20,
60
- minHeight: 44,
61
- },
62
- lg: {
63
- paddingVertical: tokens.spacing.md,
64
- paddingHorizontal: tokens.spacing.lg,
65
- fontSize: tokens.typography.bodyLarge.fontSize,
66
- iconSize: 24,
67
- minHeight: 52,
68
- },
69
- };
70
-
71
- const config = sizeConfig[size];
72
-
73
- // Variant styles
74
- const getVariantStyles = () => {
75
- const baseStyle: ViewStyle = {
76
- backgroundColor: tokens.colors.primary,
77
- borderWidth: 0,
78
- };
79
-
80
- const baseTextStyle: TextStyle = {
81
- color: tokens.colors.textInverse,
82
- };
83
-
84
- switch (variant) {
85
- case 'primary':
86
- return {
87
- container: {
88
- ...baseStyle,
89
- backgroundColor: tokens.colors.primary,
90
- },
91
- text: {
92
- ...baseTextStyle,
93
- color: tokens.colors.textInverse,
94
- },
95
- };
96
-
97
- case 'secondary':
98
- return {
99
- container: {
100
- ...baseStyle,
101
- backgroundColor: tokens.colors.surfaceSecondary,
102
- },
103
- text: {
104
- ...baseTextStyle,
105
- color: tokens.colors.textPrimary,
106
- },
107
- };
108
-
109
- case 'outline':
110
- return {
111
- container: {
112
- ...baseStyle,
113
- backgroundColor: 'transparent',
114
- borderWidth: 1,
115
- borderColor: tokens.colors.border,
116
- },
117
- text: {
118
- ...baseTextStyle,
119
- color: tokens.colors.textPrimary,
120
- },
121
- };
122
-
123
- case 'text':
124
- return {
125
- container: {
126
- ...baseStyle,
127
- backgroundColor: 'transparent',
128
- },
129
- text: {
130
- ...baseTextStyle,
131
- color: tokens.colors.primary,
132
- },
133
- };
134
-
135
- case 'danger':
136
- return {
137
- container: {
138
- ...baseStyle,
139
- backgroundColor: tokens.colors.error,
140
- },
141
- text: {
142
- ...baseTextStyle,
143
- color: tokens.colors.textInverse,
144
- },
145
- };
146
-
147
- default:
148
- return {
149
- container: baseStyle,
150
- text: baseTextStyle,
151
- };
152
- }
153
- };
154
-
155
- const variantStyles = getVariantStyles();
156
-
157
- const containerStyle: StyleProp<ViewStyle> = [
158
- styles.button,
159
- {
160
- paddingVertical: config.paddingVertical,
161
- paddingHorizontal: config.paddingHorizontal,
162
- minHeight: config.minHeight,
163
- borderRadius: tokens.borders.radius.md,
164
- },
165
- variantStyles.container,
166
- fullWidth ? styles.fullWidth : undefined,
167
- disabled ? styles.disabled : undefined,
168
- style,
169
- ];
170
-
171
- const buttonTextStyle: StyleProp<TextStyle> = [
172
- {
173
- fontSize: config.fontSize,
174
- fontWeight: '600',
175
- },
176
- variantStyles.text,
177
- disabled ? styles.disabledText : undefined,
178
- textStyle,
179
- ];
180
-
181
- const buttonText = title || children;
182
- const showIcon = icon;
183
- const iconColor = variantStyles.text.color;
184
-
185
- return (
186
- <TouchableOpacity
187
- style={containerStyle}
188
- onPress={handlePress}
189
- activeOpacity={0.8}
190
- disabled={disabled}
191
- testID={testID}
192
- >
193
- <View style={styles.content}>
194
- {showIcon ? (
195
- <Icon
196
- name={typeof icon === 'string' ? icon : String(icon)}
197
- customSize={config.iconSize}
198
- customColor={typeof iconColor === 'string' ? iconColor : undefined}
199
- style={styles.icon}
200
- />
201
- ) : null}
202
-
203
- <AtomicText style={buttonTextStyle}>
204
- {buttonText}
205
- </AtomicText>
206
- </View>
207
- </TouchableOpacity>
208
- );
209
- };
210
-
211
- const styles = StyleSheet.create({
212
- button: {
213
- alignItems: 'center',
214
- justifyContent: 'center',
215
- flexDirection: 'row',
216
- },
217
- content: {
218
- flexDirection: 'row',
219
- alignItems: 'center',
220
- justifyContent: 'center',
221
- },
222
- fullWidth: {
223
- width: '100%',
224
- },
225
- disabled: {
226
- opacity: 0.5,
227
- },
228
- disabledText: {
229
- opacity: 0.7,
230
- },
231
- icon: {
232
- marginRight: 8,
233
- },
234
- });
235
-
236
- export type { AtomicButtonProps as ButtonProps };