@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.
- 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 +148 -79
- 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,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
|
-
|
|
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
|
-
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
|
|
54
|
-
type
|
|
55
|
-
type
|
|
56
|
-
type
|
|
57
|
-
type
|
|
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
|
-
|
|
71
|
-
type SortOption,
|
|
72
|
-
type SortDirection,
|
|
73
|
-
} from '@umituz/react-native-design-system-atoms';
|
|
147
|
+
} from './atoms';
|
|
74
148
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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 '
|
|
161
|
+
} from './molecules';
|
|
162
|
+
|
|
163
|
+
// =============================================================================
|
|
164
|
+
// ORGANISMS EXPORTS
|
|
165
|
+
// =============================================================================
|
|
92
166
|
|
|
93
167
|
export {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
type
|
|
123
|
-
|
|
124
|
-
|
|
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
|
+
};
|