@umituz/react-native-design-system 1.15.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.
- package/package.json +26 -19
- package/src/atoms/AtomicAvatar.tsx +161 -0
- package/src/atoms/AtomicButton.tsx +241 -0
- package/src/atoms/AtomicChip.tsx +226 -0
- package/src/atoms/AtomicDatePicker.tsx +255 -0
- package/src/atoms/AtomicFab.tsx +99 -0
- package/src/atoms/AtomicIcon.tsx +149 -0
- package/src/atoms/AtomicInput.tsx +308 -0
- package/src/atoms/AtomicPicker.tsx +310 -0
- package/src/atoms/AtomicProgress.tsx +149 -0
- package/src/atoms/AtomicText.tsx +55 -0
- package/src/atoms/__tests__/AtomicButton.test.tsx +107 -0
- package/src/atoms/__tests__/AtomicIcon.test.tsx +110 -0
- package/src/atoms/__tests__/AtomicInput.test.tsx +195 -0
- package/src/atoms/datepicker/components/DatePickerButton.tsx +112 -0
- package/src/atoms/datepicker/components/DatePickerModal.tsx +143 -0
- package/src/atoms/fab/styles/fabStyles.ts +98 -0
- package/src/atoms/fab/types/index.ts +88 -0
- package/src/atoms/index.ts +70 -0
- package/src/atoms/input/hooks/useInputState.ts +63 -0
- package/src/atoms/input/styles/inputStylesHelper.ts +120 -0
- package/src/atoms/picker/components/PickerChips.tsx +57 -0
- package/src/atoms/picker/components/PickerModal.tsx +214 -0
- package/src/atoms/picker/styles/pickerStyles.ts +223 -0
- package/src/atoms/picker/types/index.ts +42 -0
- package/src/index.ts +133 -56
- package/src/molecules/ConfirmationModal.tsx +42 -0
- package/src/molecules/ConfirmationModalContent.tsx +87 -0
- package/src/molecules/ConfirmationModalMain.tsx +91 -0
- package/src/molecules/FormField.tsx +155 -0
- package/src/molecules/IconContainer.tsx +79 -0
- package/src/molecules/ListItem.tsx +35 -0
- package/src/molecules/ScreenHeader.tsx +171 -0
- package/src/molecules/SearchBar.tsx +198 -0
- package/src/molecules/confirmation-modal/components.tsx +94 -0
- package/src/molecules/confirmation-modal/index.ts +7 -0
- package/src/molecules/confirmation-modal/styles/confirmationModalStyles.ts +133 -0
- package/src/molecules/confirmation-modal/types/index.ts +41 -0
- package/src/molecules/confirmation-modal/useConfirmationModal.ts +50 -0
- package/src/molecules/index.ts +19 -0
- package/src/molecules/listitem/index.ts +6 -0
- package/src/molecules/listitem/styles/listItemStyles.ts +37 -0
- package/src/molecules/listitem/types/index.ts +21 -0
- package/src/organisms/AppHeader.tsx +136 -0
- package/src/organisms/FormContainer.tsx +169 -0
- package/src/organisms/ScreenLayout.tsx +183 -0
- package/src/organisms/index.ts +31 -0
- package/src/responsive/config.ts +139 -0
- package/src/responsive/deviceDetection.ts +155 -0
- package/src/responsive/gridUtils.ts +79 -0
- package/src/responsive/index.ts +52 -0
- package/src/responsive/platformConstants.ts +98 -0
- package/src/responsive/responsive.ts +61 -0
- package/src/responsive/responsiveLayout.ts +137 -0
- package/src/responsive/responsiveSizing.ts +134 -0
- package/src/responsive/useResponsive.ts +140 -0
- package/src/responsive/validation.ts +158 -0
- package/src/theme/core/BaseTokens.ts +42 -0
- package/src/theme/core/ColorPalette.ts +29 -0
- package/src/theme/core/CustomColors.ts +122 -0
- package/src/theme/core/NavigationTheme.ts +72 -0
- package/src/theme/core/TokenFactory.ts +103 -0
- package/src/theme/core/colors/ColorUtils.ts +53 -0
- package/src/theme/core/colors/DarkColors.ts +146 -0
- package/src/theme/core/colors/LightColors.ts +146 -0
- package/src/theme/core/constants/DesignConstants.ts +31 -0
- package/src/theme/core/themes.ts +118 -0
- package/src/theme/core/tokens/BaseTokens.ts +144 -0
- package/src/theme/core/tokens/Borders.ts +43 -0
- package/src/theme/core/tokens/Sizes.ts +51 -0
- package/src/theme/core/tokens/Spacing.ts +38 -0
- package/src/theme/core/tokens/Typography.ts +143 -0
- package/src/theme/hooks/useAppDesignTokens.ts +45 -0
- package/src/theme/hooks/useCommonStyles.ts +248 -0
- package/src/theme/hooks/useThemedStyles.ts +68 -0
- package/src/theme/index.ts +94 -0
- package/src/theme/infrastructure/globalThemeStore.ts +69 -0
- package/src/theme/infrastructure/storage/ThemeStorage.ts +93 -0
- package/src/theme/infrastructure/stores/themeStore.ts +109 -0
- package/src/typography/__tests__/colorValidationUtils.test.ts +180 -0
- package/src/typography/__tests__/textColorUtils.test.ts +185 -0
- package/src/typography/__tests__/textStyleUtils.test.ts +168 -0
- package/src/typography/domain/entities/TypographyTypes.ts +88 -0
- package/src/typography/index.ts +53 -0
- package/src/typography/presentation/utils/colorValidationUtils.ts +133 -0
- package/src/typography/presentation/utils/textColorUtils.ts +205 -0
- 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,36 +1,121 @@
|
|
|
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
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
type VariantProps,
|
|
14
|
-
} from './presentation/utils/variants/core';
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// TYPOGRAPHY EXPORTS
|
|
60
|
+
// =============================================================================
|
|
15
61
|
|
|
16
62
|
export {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
120
|
AtomicAvatar,
|
|
36
121
|
AtomicChip,
|
|
@@ -49,9 +134,6 @@ export {
|
|
|
49
134
|
type AtomicInputVariant,
|
|
50
135
|
type AtomicInputState,
|
|
51
136
|
type AtomicInputSize,
|
|
52
|
-
type AtomicCardProps,
|
|
53
|
-
type AtomicCardVariant,
|
|
54
|
-
type AtomicCardPadding,
|
|
55
137
|
type AtomicFabProps,
|
|
56
138
|
type FabSize,
|
|
57
139
|
type FabVariant,
|
|
@@ -62,55 +144,50 @@ export {
|
|
|
62
144
|
type PickerOption,
|
|
63
145
|
type PickerSize,
|
|
64
146
|
type AtomicDatePickerProps,
|
|
65
|
-
} from '
|
|
147
|
+
} from './atoms';
|
|
66
148
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
149
|
+
// =============================================================================
|
|
150
|
+
// MOLECULES EXPORTS
|
|
151
|
+
// =============================================================================
|
|
70
152
|
|
|
71
153
|
export {
|
|
72
154
|
FormField,
|
|
73
155
|
ListItem,
|
|
74
156
|
SearchBar,
|
|
75
|
-
SectionCard,
|
|
76
157
|
IconContainer,
|
|
77
158
|
ScreenHeader,
|
|
78
|
-
SectionHeader,
|
|
79
|
-
SectionContainer,
|
|
80
|
-
GridContainer,
|
|
81
159
|
ConfirmationModal,
|
|
82
160
|
useConfirmationModal,
|
|
83
|
-
} from '
|
|
161
|
+
} from './molecules';
|
|
162
|
+
|
|
163
|
+
// =============================================================================
|
|
164
|
+
// ORGANISMS EXPORTS
|
|
165
|
+
// =============================================================================
|
|
84
166
|
|
|
85
167
|
export {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
getResponsiveFABPosition,
|
|
95
|
-
getResponsiveModalMaxHeight,
|
|
96
|
-
getResponsiveMinModalHeight,
|
|
97
|
-
getResponsiveIconContainerSize,
|
|
98
|
-
getResponsiveGridColumns,
|
|
99
|
-
getResponsiveMaxWidth,
|
|
100
|
-
getResponsiveFontSize,
|
|
101
|
-
isLandscape,
|
|
102
|
-
getDeviceType,
|
|
103
|
-
getMinTouchTarget,
|
|
104
|
-
getSpacingMultiplier,
|
|
105
|
-
IOS_HIG,
|
|
106
|
-
PLATFORM_CONSTANTS,
|
|
107
|
-
isValidTouchTarget,
|
|
108
|
-
DeviceType,
|
|
109
|
-
} from '@umituz/react-native-design-system-responsive';
|
|
168
|
+
ScreenLayout,
|
|
169
|
+
AppHeader,
|
|
170
|
+
FormContainer,
|
|
171
|
+
} from './organisms';
|
|
172
|
+
|
|
173
|
+
// =============================================================================
|
|
174
|
+
// VARIANT UTILITIES
|
|
175
|
+
// =============================================================================
|
|
110
176
|
|
|
111
177
|
export {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
type
|
|
115
|
-
|
|
116
|
-
|
|
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
|
+
};
|