@umituz/react-native-design-system 1.14.0 → 2.0.0

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 (87) hide show
  1. package/package.json +26 -19
  2. package/src/atoms/AtomicAvatar.tsx +161 -0
  3. package/src/atoms/AtomicButton.tsx +241 -0
  4. package/src/atoms/AtomicChip.tsx +226 -0
  5. package/src/atoms/AtomicDatePicker.tsx +255 -0
  6. package/src/atoms/AtomicFab.tsx +99 -0
  7. package/src/atoms/AtomicIcon.tsx +149 -0
  8. package/src/atoms/AtomicInput.tsx +308 -0
  9. package/src/atoms/AtomicPicker.tsx +310 -0
  10. package/src/atoms/AtomicProgress.tsx +149 -0
  11. package/src/atoms/AtomicText.tsx +55 -0
  12. package/src/atoms/__tests__/AtomicButton.test.tsx +107 -0
  13. package/src/atoms/__tests__/AtomicIcon.test.tsx +110 -0
  14. package/src/atoms/__tests__/AtomicInput.test.tsx +195 -0
  15. package/src/atoms/datepicker/components/DatePickerButton.tsx +112 -0
  16. package/src/atoms/datepicker/components/DatePickerModal.tsx +143 -0
  17. package/src/atoms/fab/styles/fabStyles.ts +98 -0
  18. package/src/atoms/fab/types/index.ts +88 -0
  19. package/src/atoms/index.ts +70 -0
  20. package/src/atoms/input/hooks/useInputState.ts +63 -0
  21. package/src/atoms/input/styles/inputStylesHelper.ts +120 -0
  22. package/src/atoms/picker/components/PickerChips.tsx +57 -0
  23. package/src/atoms/picker/components/PickerModal.tsx +214 -0
  24. package/src/atoms/picker/styles/pickerStyles.ts +223 -0
  25. package/src/atoms/picker/types/index.ts +42 -0
  26. package/src/index.ts +148 -79
  27. package/src/molecules/ConfirmationModal.tsx +42 -0
  28. package/src/molecules/ConfirmationModalContent.tsx +87 -0
  29. package/src/molecules/ConfirmationModalMain.tsx +91 -0
  30. package/src/molecules/FormField.tsx +155 -0
  31. package/src/molecules/IconContainer.tsx +79 -0
  32. package/src/molecules/ListItem.tsx +35 -0
  33. package/src/molecules/ScreenHeader.tsx +171 -0
  34. package/src/molecules/SearchBar.tsx +198 -0
  35. package/src/molecules/confirmation-modal/components.tsx +94 -0
  36. package/src/molecules/confirmation-modal/index.ts +7 -0
  37. package/src/molecules/confirmation-modal/styles/confirmationModalStyles.ts +133 -0
  38. package/src/molecules/confirmation-modal/types/index.ts +41 -0
  39. package/src/molecules/confirmation-modal/useConfirmationModal.ts +50 -0
  40. package/src/molecules/index.ts +19 -0
  41. package/src/molecules/listitem/index.ts +6 -0
  42. package/src/molecules/listitem/styles/listItemStyles.ts +37 -0
  43. package/src/molecules/listitem/types/index.ts +21 -0
  44. package/src/organisms/AppHeader.tsx +136 -0
  45. package/src/organisms/FormContainer.tsx +169 -0
  46. package/src/organisms/ScreenLayout.tsx +183 -0
  47. package/src/organisms/index.ts +31 -0
  48. package/src/responsive/config.ts +139 -0
  49. package/src/responsive/deviceDetection.ts +155 -0
  50. package/src/responsive/gridUtils.ts +79 -0
  51. package/src/responsive/index.ts +52 -0
  52. package/src/responsive/platformConstants.ts +98 -0
  53. package/src/responsive/responsive.ts +61 -0
  54. package/src/responsive/responsiveLayout.ts +137 -0
  55. package/src/responsive/responsiveSizing.ts +134 -0
  56. package/src/responsive/useResponsive.ts +140 -0
  57. package/src/responsive/validation.ts +158 -0
  58. package/src/theme/core/BaseTokens.ts +42 -0
  59. package/src/theme/core/ColorPalette.ts +29 -0
  60. package/src/theme/core/CustomColors.ts +122 -0
  61. package/src/theme/core/NavigationTheme.ts +72 -0
  62. package/src/theme/core/TokenFactory.ts +103 -0
  63. package/src/theme/core/colors/ColorUtils.ts +53 -0
  64. package/src/theme/core/colors/DarkColors.ts +146 -0
  65. package/src/theme/core/colors/LightColors.ts +146 -0
  66. package/src/theme/core/constants/DesignConstants.ts +31 -0
  67. package/src/theme/core/themes.ts +118 -0
  68. package/src/theme/core/tokens/BaseTokens.ts +144 -0
  69. package/src/theme/core/tokens/Borders.ts +43 -0
  70. package/src/theme/core/tokens/Sizes.ts +51 -0
  71. package/src/theme/core/tokens/Spacing.ts +38 -0
  72. package/src/theme/core/tokens/Typography.ts +143 -0
  73. package/src/theme/hooks/useAppDesignTokens.ts +45 -0
  74. package/src/theme/hooks/useCommonStyles.ts +248 -0
  75. package/src/theme/hooks/useThemedStyles.ts +68 -0
  76. package/src/theme/index.ts +94 -0
  77. package/src/theme/infrastructure/globalThemeStore.ts +69 -0
  78. package/src/theme/infrastructure/storage/ThemeStorage.ts +93 -0
  79. package/src/theme/infrastructure/stores/themeStore.ts +109 -0
  80. package/src/typography/__tests__/colorValidationUtils.test.ts +180 -0
  81. package/src/typography/__tests__/textColorUtils.test.ts +185 -0
  82. package/src/typography/__tests__/textStyleUtils.test.ts +168 -0
  83. package/src/typography/domain/entities/TypographyTypes.ts +88 -0
  84. package/src/typography/index.ts +53 -0
  85. package/src/typography/presentation/utils/colorValidationUtils.ts +133 -0
  86. package/src/typography/presentation/utils/textColorUtils.ts +205 -0
  87. package/src/typography/presentation/utils/textStyleUtils.ts +159 -0
@@ -0,0 +1,223 @@
1
+ /**
2
+ * AtomicPicker Styles
3
+ */
4
+ import type { ViewStyle, TextStyle } from 'react-native';
5
+ import type { DesignTokens } from '../../../theme';
6
+
7
+ export type PickerSize = 'sm' | 'md' | 'lg';
8
+
9
+ export interface PickerContainerStyles {
10
+ base: ViewStyle;
11
+ size: Record<PickerSize, ViewStyle>;
12
+ state: {
13
+ error: ViewStyle;
14
+ disabled: ViewStyle;
15
+ };
16
+ }
17
+
18
+ export interface PickerLabelStyles {
19
+ base: TextStyle;
20
+ size: Record<PickerSize, TextStyle>;
21
+ }
22
+
23
+ export interface PickerValueStyles {
24
+ base: TextStyle;
25
+ size: Record<PickerSize, TextStyle>;
26
+ }
27
+
28
+ export interface PickerPlaceholderStyles {
29
+ base: TextStyle;
30
+ size: Record<PickerSize, TextStyle>;
31
+ }
32
+
33
+ export const getPickerContainerStyles = (tokens: DesignTokens): PickerContainerStyles => ({
34
+ base: {
35
+ flexDirection: 'row',
36
+ alignItems: 'center',
37
+ justifyContent: 'space-between',
38
+ borderWidth: 1,
39
+ borderColor: tokens.colors.outline,
40
+ backgroundColor: tokens.colors.surface,
41
+ borderRadius: tokens.borders.radius.md,
42
+ },
43
+ size: {
44
+ sm: {
45
+ paddingHorizontal: tokens.spacing.sm,
46
+ paddingVertical: tokens.spacing.xs,
47
+ minHeight: 36,
48
+ },
49
+ md: {
50
+ paddingHorizontal: tokens.spacing.md,
51
+ paddingVertical: tokens.spacing.sm,
52
+ minHeight: 48,
53
+ },
54
+ lg: {
55
+ paddingHorizontal: tokens.spacing.lg,
56
+ paddingVertical: tokens.spacing.md,
57
+ minHeight: 56,
58
+ },
59
+ },
60
+ state: {
61
+ error: {
62
+ borderColor: tokens.colors.error,
63
+ },
64
+ disabled: {
65
+ opacity: tokens.opacity.disabled,
66
+ },
67
+ },
68
+ });
69
+
70
+ export const getPickerLabelStyles = (tokens: DesignTokens): PickerLabelStyles => ({
71
+ base: {
72
+ color: tokens.colors.textPrimary,
73
+ marginBottom: tokens.spacing.xs,
74
+ },
75
+ size: {
76
+ sm: { fontSize: tokens.typography.bodySmall.fontSize },
77
+ md: { fontSize: tokens.typography.bodyMedium.fontSize },
78
+ lg: { fontSize: tokens.typography.bodyLarge.fontSize },
79
+ },
80
+ });
81
+
82
+ export const getPickerValueStyles = (tokens: DesignTokens): PickerValueStyles => ({
83
+ base: {
84
+ color: tokens.colors.textPrimary,
85
+ flex: 1,
86
+ },
87
+ size: {
88
+ sm: { fontSize: tokens.typography.bodySmall.fontSize },
89
+ md: { fontSize: tokens.typography.bodyMedium.fontSize },
90
+ lg: { fontSize: tokens.typography.bodyLarge.fontSize },
91
+ },
92
+ });
93
+
94
+ export const getPickerPlaceholderStyles = (tokens: DesignTokens): PickerPlaceholderStyles => ({
95
+ base: {
96
+ color: tokens.colors.textTertiary,
97
+ flex: 1,
98
+ },
99
+ size: {
100
+ sm: { fontSize: tokens.typography.bodySmall.fontSize },
101
+ md: { fontSize: tokens.typography.bodyMedium.fontSize },
102
+ lg: { fontSize: tokens.typography.bodyLarge.fontSize },
103
+ },
104
+ });
105
+
106
+ export const getPickerErrorStyles = (tokens: DesignTokens): TextStyle => ({
107
+ color: tokens.colors.error,
108
+ fontSize: tokens.typography.bodySmall.fontSize,
109
+ marginTop: tokens.spacing.xs,
110
+ });
111
+
112
+ // Modal styles
113
+ export const getModalOverlayStyles = (tokens: DesignTokens): ViewStyle => ({
114
+ flex: 1,
115
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
116
+ justifyContent: 'flex-end',
117
+ });
118
+
119
+ export const getModalContainerStyles = (tokens: DesignTokens, bottomInset: number): ViewStyle => ({
120
+ backgroundColor: tokens.colors.surface,
121
+ borderTopLeftRadius: tokens.borders.radius.lg,
122
+ borderTopRightRadius: tokens.borders.radius.lg,
123
+ maxHeight: '80%',
124
+ paddingBottom: bottomInset,
125
+ });
126
+
127
+ export const getModalHeaderStyles = (tokens: DesignTokens): ViewStyle => ({
128
+ flexDirection: 'row',
129
+ justifyContent: 'space-between',
130
+ alignItems: 'center',
131
+ paddingHorizontal: tokens.spacing.md,
132
+ paddingVertical: tokens.spacing.md,
133
+ borderBottomWidth: 1,
134
+ borderBottomColor: tokens.colors.outline,
135
+ });
136
+
137
+ export const getModalTitleStyles = (tokens: DesignTokens): TextStyle => ({
138
+ fontSize: tokens.typography.titleLarge.fontSize,
139
+ fontWeight: '600',
140
+ color: tokens.colors.onSurface,
141
+ });
142
+
143
+ export const getSearchContainerStyles = (tokens: DesignTokens): ViewStyle => ({
144
+ flexDirection: 'row',
145
+ alignItems: 'center',
146
+ backgroundColor: tokens.colors.surfaceVariant,
147
+ borderRadius: tokens.borders.radius.md,
148
+ marginHorizontal: tokens.spacing.md,
149
+ marginVertical: tokens.spacing.sm,
150
+ paddingHorizontal: tokens.spacing.md,
151
+ paddingVertical: tokens.spacing.sm,
152
+ gap: tokens.spacing.sm,
153
+ });
154
+
155
+ export const getSearchInputStyles = (tokens: DesignTokens): TextStyle => ({
156
+ flex: 1,
157
+ fontSize: tokens.typography.bodyMedium.fontSize,
158
+ color: tokens.colors.onSurface,
159
+ paddingVertical: 0,
160
+ });
161
+
162
+ export const getOptionContainerStyles = (
163
+ tokens: DesignTokens,
164
+ selected: boolean,
165
+ disabled: boolean
166
+ ): ViewStyle => ({
167
+ flexDirection: 'row',
168
+ alignItems: 'center',
169
+ paddingHorizontal: tokens.spacing.md,
170
+ paddingVertical: tokens.spacing.md,
171
+ gap: tokens.spacing.md,
172
+ backgroundColor: selected ? tokens.colors.surfaceVariant : 'transparent',
173
+ opacity: disabled ? tokens.opacity.disabled : 1,
174
+ });
175
+
176
+ export const getOptionTextStyles = (tokens: DesignTokens, selected: boolean): TextStyle => ({
177
+ fontSize: tokens.typography.bodyLarge.fontSize,
178
+ color: selected ? tokens.colors.primary : tokens.colors.onSurface,
179
+ fontWeight: selected ? '600' : '400',
180
+ });
181
+
182
+ export const getOptionDescriptionStyles = (tokens: DesignTokens): TextStyle => ({
183
+ fontSize: tokens.typography.bodySmall.fontSize,
184
+ color: tokens.colors.textSecondary,
185
+ marginTop: tokens.spacing.xs,
186
+ });
187
+
188
+ export const getEmptyStateStyles = (tokens: DesignTokens): ViewStyle => ({
189
+ flex: 1,
190
+ justifyContent: 'center',
191
+ alignItems: 'center',
192
+ paddingVertical: tokens.spacing.xl,
193
+ gap: tokens.spacing.md,
194
+ });
195
+
196
+ export const getEmptyStateTextStyles = (tokens: DesignTokens): TextStyle => ({
197
+ fontSize: tokens.typography.bodyMedium.fontSize,
198
+ color: tokens.colors.textSecondary,
199
+ textAlign: 'center',
200
+ });
201
+
202
+ // Chip styles
203
+ export const getChipContainerStyles = (tokens: DesignTokens): ViewStyle => ({
204
+ flexDirection: 'row',
205
+ flexWrap: 'wrap',
206
+ gap: tokens.spacing.xs,
207
+ marginTop: tokens.spacing.sm,
208
+ });
209
+
210
+ export const getChipStyles = (tokens: DesignTokens): ViewStyle => ({
211
+ flexDirection: 'row',
212
+ alignItems: 'center',
213
+ backgroundColor: tokens.colors.surfaceVariant,
214
+ borderRadius: tokens.borders.radius.full,
215
+ paddingHorizontal: tokens.spacing.sm,
216
+ paddingVertical: tokens.spacing.xs,
217
+ gap: tokens.spacing.xs,
218
+ });
219
+
220
+ export const getChipTextStyles = (tokens: DesignTokens): TextStyle => ({
221
+ fontSize: tokens.typography.bodySmall.fontSize,
222
+ color: tokens.colors.onSurface,
223
+ });
@@ -0,0 +1,42 @@
1
+ import { ViewStyle, TextStyle } from 'react-native';
2
+ import { IconColor } from '../../AtomicIcon';
3
+
4
+ /**
5
+ * Picker option item
6
+ *
7
+ * icon: Any MaterialIcons name
8
+ * @see https://fonts.google.com/icons
9
+ */
10
+ export interface PickerOption {
11
+ label: string;
12
+ value: string;
13
+ icon?: string; // MaterialIcons name
14
+ disabled?: boolean;
15
+ description?: string;
16
+ testID?: string;
17
+ }
18
+
19
+ export type PickerSize = 'sm' | 'md' | 'lg';
20
+
21
+ export interface AtomicPickerProps {
22
+ value: string | string[];
23
+ onChange: (value: string | string[]) => void;
24
+ options: PickerOption[];
25
+ label?: string;
26
+ placeholder?: string;
27
+ error?: string;
28
+ disabled?: boolean;
29
+ multiple?: boolean;
30
+ searchable?: boolean;
31
+ clearable?: boolean;
32
+ autoClose?: boolean;
33
+ color?: IconColor;
34
+ size?: PickerSize;
35
+ modalTitle?: string;
36
+ emptyMessage?: string;
37
+ clearAccessibilityLabel?: string;
38
+ closeAccessibilityLabel?: string;
39
+ style?: ViewStyle | ViewStyle[];
40
+ labelStyle?: TextStyle | TextStyle[];
41
+ testID?: string;
42
+ }
package/src/index.ts CHANGED
@@ -1,124 +1,193 @@
1
1
  /**
2
2
  * @umituz/react-native-design-system
3
3
  * Universal design system for React Native apps
4
+ *
5
+ * Consolidated package including:
6
+ * - Atoms (primitive UI components)
7
+ * - Molecules (composite components)
8
+ * - Organisms (complex UI patterns)
9
+ * - Theme (design tokens, colors)
10
+ * - Typography (text styles)
11
+ * - Responsive (screen utilities)
4
12
  */
5
13
 
14
+ // =============================================================================
15
+ // THEME EXPORTS
16
+ // =============================================================================
17
+
6
18
  export {
19
+ useAppDesignTokens,
7
20
  useCommonStyles,
8
- } from '@umituz/react-native-design-system-theme';
21
+ useDesignSystemTheme,
22
+ useTheme,
23
+ useThemedStyles,
24
+ useThemedStyleSheet,
25
+ lightColors,
26
+ darkColors,
27
+ getColorPalette,
28
+ withAlpha,
29
+ BASE_TOKENS,
30
+ BASE_TOKENS as STATIC_TOKENS,
31
+ spacing,
32
+ typography,
33
+ borders,
34
+ createDesignTokens,
35
+ lightTheme,
36
+ darkTheme,
37
+ createResponsiveValue,
38
+ ThemeStorage,
39
+ createNavigationTheme,
40
+ applyCustomColors,
41
+ type ColorPalette,
42
+ type ThemeMode,
43
+ type CustomThemeColors,
44
+ type Spacing,
45
+ type Typography,
46
+ type Borders,
47
+ type BaseTokens,
48
+ type IconSizes,
49
+ type Opacity,
50
+ type AvatarSizes,
51
+ type ComponentSizes,
52
+ type DesignTokens,
53
+ type Theme,
54
+ type ExtendedColorPalette,
55
+ type NavigationTheme,
56
+ } from './theme';
9
57
 
10
- export {
11
- createVariants,
12
- type VariantConfig,
13
- type VariantProps,
14
- } from './presentation/utils/variants/core';
58
+ // =============================================================================
59
+ // TYPOGRAPHY EXPORTS
60
+ // =============================================================================
15
61
 
16
62
  export {
17
- createAdvancedVariants,
18
- type AdvancedVariantConfig,
19
- type CompoundVariant,
20
- } from './presentation/utils/variants/compound';
63
+ getTextColor,
64
+ getTextStyle,
65
+ isTextStyleVariant,
66
+ getAllTextStyleVariants,
67
+ clearTypographyCache,
68
+ clearColorCache,
69
+ isValidHexColor,
70
+ isValidRgbColor,
71
+ isValidHslColor,
72
+ isValidNamedColor,
73
+ isValidColor,
74
+ getColorFormat,
75
+ normalizeColor,
76
+ type TextStyleVariant,
77
+ type ColorVariant,
78
+ } from './typography';
79
+
80
+ // =============================================================================
81
+ // RESPONSIVE EXPORTS
82
+ // =============================================================================
21
83
 
22
84
  export {
23
- conditionalStyle,
24
- responsiveStyle,
25
- combineStyles,
26
- } from './presentation/utils/variants/helpers';
85
+ useResponsive,
86
+ getScreenDimensions,
87
+ isSmallPhone,
88
+ isTablet,
89
+ getResponsiveLogoSize,
90
+ getResponsiveInputHeight,
91
+ getResponsiveHorizontalPadding,
92
+ getResponsiveBottomPosition,
93
+ getResponsiveFABPosition,
94
+ getResponsiveModalMaxHeight,
95
+ getResponsiveMinModalHeight,
96
+ getResponsiveIconContainerSize,
97
+ getResponsiveGridColumns,
98
+ getResponsiveMaxWidth,
99
+ getResponsiveFontSize,
100
+ isLandscape,
101
+ getDeviceType,
102
+ getMinTouchTarget,
103
+ getSpacingMultiplier,
104
+ IOS_HIG,
105
+ PLATFORM_CONSTANTS,
106
+ isValidTouchTarget,
107
+ DeviceType,
108
+ } from './responsive';
109
+
110
+ // =============================================================================
111
+ // ATOMS EXPORTS
112
+ // =============================================================================
27
113
 
28
114
  export {
29
115
  AtomicText,
30
116
  AtomicIcon,
31
117
  AtomicButton,
32
118
  AtomicInput,
33
- AtomicCard,
34
119
  AtomicFab,
35
- AtomicSearchBar,
36
- AtomicSwitch,
37
- AtomicTextArea,
38
- AtomicImage,
39
- AtomicBadge,
40
- AtomicFormError,
41
120
  AtomicAvatar,
42
121
  AtomicChip,
43
- AtomicDivider,
44
122
  AtomicProgress,
45
- AtomicAvatarGroup,
46
- AtomicFilter,
47
- AtomicTouchable,
48
- AtomicNumberInput,
49
123
  AtomicPicker,
50
124
  AtomicDatePicker,
51
- AtomicSort,
52
125
  type IconName,
53
- type AtomicSwitchProps,
54
- type AtomicTextAreaProps,
55
- type AtomicImageProps,
56
- type AtomicBadgeProps,
57
- type AtomicFormErrorProps,
126
+ type IconSize,
127
+ type IconColor,
128
+ type AtomicTextProps,
129
+ type AtomicIconProps,
130
+ type AtomicButtonProps,
131
+ type ButtonVariant,
132
+ type ButtonSize,
133
+ type AtomicInputProps,
134
+ type AtomicInputVariant,
135
+ type AtomicInputState,
136
+ type AtomicInputSize,
137
+ type AtomicFabProps,
138
+ type FabSize,
139
+ type FabVariant,
58
140
  type AtomicAvatarProps,
59
141
  type AtomicChipProps,
60
- type AtomicDividerProps,
61
142
  type AtomicProgressProps,
62
- type AtomicAvatarGroupProps,
63
- type AtomicFilterProps,
64
- type FilterOption,
65
- type AtomicTouchableProps,
66
- type AtomicNumberInputProps,
67
143
  type AtomicPickerProps,
68
144
  type PickerOption,
145
+ type PickerSize,
69
146
  type AtomicDatePickerProps,
70
- type AtomicSortProps,
71
- type SortOption,
72
- type SortDirection,
73
- } from '@umituz/react-native-design-system-atoms';
147
+ } from './atoms';
74
148
 
75
- export {
76
- ScreenLayout,
77
- } from '@umituz/react-native-design-system-organisms';
149
+ // =============================================================================
150
+ // MOLECULES EXPORTS
151
+ // =============================================================================
78
152
 
79
153
  export {
80
154
  FormField,
81
155
  ListItem,
82
156
  SearchBar,
83
- SectionCard,
84
157
  IconContainer,
85
158
  ScreenHeader,
86
- SectionHeader,
87
- SectionContainer,
88
- GridContainer,
89
159
  ConfirmationModal,
90
160
  useConfirmationModal,
91
- } from '@umituz/react-native-design-system-molecules';
161
+ } from './molecules';
162
+
163
+ // =============================================================================
164
+ // ORGANISMS EXPORTS
165
+ // =============================================================================
92
166
 
93
167
  export {
94
- useResponsive,
95
- getScreenDimensions,
96
- isSmallPhone,
97
- isTablet,
98
- getResponsiveLogoSize,
99
- getResponsiveInputHeight,
100
- getResponsiveHorizontalPadding,
101
- getResponsiveBottomPosition,
102
- getResponsiveFABPosition,
103
- getResponsiveModalMaxHeight,
104
- getResponsiveMinModalHeight,
105
- getResponsiveIconContainerSize,
106
- getResponsiveGridColumns,
107
- getResponsiveMaxWidth,
108
- getResponsiveFontSize,
109
- isLandscape,
110
- getDeviceType,
111
- getMinTouchTarget,
112
- getSpacingMultiplier,
113
- IOS_HIG,
114
- PLATFORM_CONSTANTS,
115
- isValidTouchTarget,
116
- DeviceType,
117
- } from '@umituz/react-native-design-system-responsive';
168
+ ScreenLayout,
169
+ AppHeader,
170
+ FormContainer,
171
+ } from './organisms';
172
+
173
+ // =============================================================================
174
+ // VARIANT UTILITIES
175
+ // =============================================================================
118
176
 
119
177
  export {
120
- useAppDesignTokens,
121
- STATIC_TOKENS,
122
- type DesignTokens,
123
- withAlpha,
124
- } from '@umituz/react-native-design-system-theme';
178
+ createVariants,
179
+ type VariantConfig,
180
+ type VariantProps,
181
+ } from './presentation/utils/variants/core';
182
+
183
+ export {
184
+ createAdvancedVariants,
185
+ type AdvancedVariantConfig,
186
+ type CompoundVariant,
187
+ } from './presentation/utils/variants/compound';
188
+
189
+ export {
190
+ conditionalStyle,
191
+ responsiveStyle,
192
+ combineStyles,
193
+ } from './presentation/utils/variants/helpers';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * ConfirmationModal - Universal Confirmation Dialog
3
+ *
4
+ * A reusable confirmation modal for destructive and important actions.
5
+ * Follows Material Design 3 dialog patterns and accessibility guidelines.
6
+ *
7
+ * Features:
8
+ * - Multiple variants (default, destructive, warning, success)
9
+ * - Configurable text and icons
10
+ * - Backdrop dismissal
11
+ * - Full keyboard and screen reader support
12
+ * - Theme-aware styling
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * // Destructive confirmation (delete)
17
+ * <ConfirmationModal
18
+ * visible={showDeleteModal}
19
+ * variant="destructive"
20
+ * title="Delete Item?"
21
+ * message="This action cannot be undone. All data will be permanently deleted."
22
+ * confirmText="Delete"
23
+ * cancelText="Cancel"
24
+ * onConfirm={handleDelete}
25
+ * onCancel={() => setShowDeleteModal(false)}
26
+ * />
27
+ *
28
+ * // Generic confirmation
29
+ * <ConfirmationModal
30
+ * visible={showConfirmModal}
31
+ * variant="default"
32
+ * title="Confirm Action"
33
+ * message="Are you sure you want to proceed?"
34
+ * onConfirm={handleConfirm}
35
+ * onCancel={() => setShowConfirmModal(false)}
36
+ * />
37
+ * ```
38
+ */
39
+
40
+ export { ConfirmationModal } from './ConfirmationModalMain';
41
+ export { useConfirmationModal } from './confirmation-modal/useConfirmationModal';
42
+ export type { ConfirmationModalProps, ConfirmationModalVariant } from './confirmation-modal/types';
@@ -0,0 +1,87 @@
1
+ /**
2
+ * ConfirmationModal Content Component
3
+ *
4
+ * Content component for confirmation modal
5
+ */
6
+
7
+ import React from 'react';
8
+ import { View, ViewStyle, StyleProp } from 'react-native';
9
+ import { useAppDesignTokens } from '../theme';
10
+ import { ConfirmationModalVariant } from './confirmation-modal/types/';
11
+ import {
12
+ getVariantConfig,
13
+ getModalContainerStyle,
14
+ getIconContainerStyle,
15
+ getTitleContainerStyle,
16
+ getMessageContainerStyle,
17
+ getButtonStyle,
18
+ } from './confirmation-modal/styles/confirmationModalStyles';
19
+ import {
20
+ ConfirmationModalIcon,
21
+ ConfirmationModalTitle,
22
+ ConfirmationModalMessage,
23
+ ConfirmationModalButtons,
24
+ } from './confirmation-modal/components';
25
+
26
+ const useConfirmButtonStyle = (
27
+ variant: ConfirmationModalVariant,
28
+ tokens: ReturnType<typeof useAppDesignTokens>
29
+ ) => {
30
+ return React.useCallback(() => {
31
+ const baseStyle = getButtonStyle();
32
+ const variantStyles = [];
33
+
34
+ if (variant === 'destructive') variantStyles.push({ backgroundColor: tokens.colors.error });
35
+ if (variant === 'warning') variantStyles.push({ backgroundColor: tokens.colors.warning });
36
+ if (variant === 'success') variantStyles.push({ backgroundColor: tokens.colors.success });
37
+
38
+ return [baseStyle, ...variantStyles];
39
+ }, [variant, tokens.colors]);
40
+ };
41
+
42
+ export const ConfirmationModalContent: React.FC<{
43
+ tokens: ReturnType<typeof useAppDesignTokens>;
44
+ variant: ConfirmationModalVariant;
45
+ title: string;
46
+ message: string;
47
+ confirmText: string;
48
+ cancelText: string;
49
+ icon?: string;
50
+ onConfirm: () => void;
51
+ onCancel: () => void;
52
+ style?: StyleProp<ViewStyle>;
53
+ testID: string;
54
+ }> = ({ tokens, variant, title, message, confirmText, cancelText, icon, onConfirm, onCancel, style, testID }) => {
55
+ const variantConfig = getVariantConfig(variant as 'default' | 'destructive' | 'warning' | 'success', tokens);
56
+ const finalIcon = icon || variantConfig.icon;
57
+ const getConfirmButtonStyle = useConfirmButtonStyle(variant, tokens);
58
+
59
+ return (
60
+ <View style={[getModalContainerStyle(tokens), style]}>
61
+ <View style={getIconContainerStyle(tokens)}>
62
+ <ConfirmationModalIcon
63
+ icon={finalIcon}
64
+ iconColor={variantConfig.iconColor}
65
+ testID={testID}
66
+ />
67
+ </View>
68
+
69
+ <View style={getTitleContainerStyle(tokens)}>
70
+ <ConfirmationModalTitle title={title} tokens={tokens} testID={testID} />
71
+ </View>
72
+
73
+ <View style={getMessageContainerStyle(tokens)}>
74
+ <ConfirmationModalMessage message={message} tokens={tokens} testID={testID} />
75
+ </View>
76
+
77
+ <ConfirmationModalButtons
78
+ confirmText={confirmText}
79
+ cancelText={cancelText}
80
+ onConfirm={onConfirm}
81
+ onCancel={onCancel}
82
+ confirmButtonStyle={getConfirmButtonStyle()}
83
+ testID={testID}
84
+ />
85
+ </View>
86
+ );
87
+ };