@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,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BASE TOKENS - Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for all static design tokens
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { TextStyle, ViewStyle } from 'react-native';
|
|
8
|
+
|
|
9
|
+
export type Spacing = {
|
|
10
|
+
// Base Spacing Scale
|
|
11
|
+
xs: number;
|
|
12
|
+
sm: number;
|
|
13
|
+
md: number;
|
|
14
|
+
lg: number;
|
|
15
|
+
xl: number;
|
|
16
|
+
xxl: number;
|
|
17
|
+
xxxl: number;
|
|
18
|
+
|
|
19
|
+
// Semantic Spacing
|
|
20
|
+
screenPadding: number;
|
|
21
|
+
cardPadding: number;
|
|
22
|
+
buttonPadding: number;
|
|
23
|
+
inputPadding: number;
|
|
24
|
+
sectionSpacing: number;
|
|
25
|
+
|
|
26
|
+
// Icon Sizes
|
|
27
|
+
iconSizeSmall: number;
|
|
28
|
+
iconSizeMedium: number;
|
|
29
|
+
iconSizeLarge: number;
|
|
30
|
+
iconSizeXLarge: number;
|
|
31
|
+
iconSizeHero: number;
|
|
32
|
+
|
|
33
|
+
// Component Heights
|
|
34
|
+
buttonHeight: number;
|
|
35
|
+
inputHeight: number;
|
|
36
|
+
appBarHeight: number;
|
|
37
|
+
tabBarHeight: number;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type Typography = {
|
|
41
|
+
displayLarge: TextStyle;
|
|
42
|
+
displayMedium: TextStyle;
|
|
43
|
+
displaySmall: TextStyle;
|
|
44
|
+
headlineLarge: TextStyle;
|
|
45
|
+
headlineMedium: TextStyle;
|
|
46
|
+
headlineSmall: TextStyle;
|
|
47
|
+
titleLarge: TextStyle;
|
|
48
|
+
titleMedium: TextStyle;
|
|
49
|
+
titleSmall: TextStyle;
|
|
50
|
+
bodyLarge: TextStyle;
|
|
51
|
+
bodyMedium: TextStyle;
|
|
52
|
+
bodySmall: TextStyle;
|
|
53
|
+
labelLarge: TextStyle;
|
|
54
|
+
labelMedium: TextStyle;
|
|
55
|
+
labelSmall: TextStyle;
|
|
56
|
+
button: TextStyle;
|
|
57
|
+
caption: TextStyle;
|
|
58
|
+
overline: TextStyle;
|
|
59
|
+
// Legacy compatibility
|
|
60
|
+
headingLarge: TextStyle;
|
|
61
|
+
headingMedium: TextStyle;
|
|
62
|
+
headingSmall: TextStyle;
|
|
63
|
+
// Font weight helpers (for inline fontWeight usage)
|
|
64
|
+
semibold: '600';
|
|
65
|
+
medium: '500';
|
|
66
|
+
bold: '700';
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type Borders = {
|
|
70
|
+
radius: {
|
|
71
|
+
none: number;
|
|
72
|
+
xs: number;
|
|
73
|
+
sm: number;
|
|
74
|
+
md: number;
|
|
75
|
+
lg: number;
|
|
76
|
+
xl: number;
|
|
77
|
+
xxl: number;
|
|
78
|
+
full: number;
|
|
79
|
+
};
|
|
80
|
+
width: {
|
|
81
|
+
none: number;
|
|
82
|
+
thin: number;
|
|
83
|
+
medium: number;
|
|
84
|
+
thick: number;
|
|
85
|
+
};
|
|
86
|
+
button: ViewStyle;
|
|
87
|
+
card: ViewStyle;
|
|
88
|
+
input: ViewStyle;
|
|
89
|
+
pill: ViewStyle;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export type IconSizes = {
|
|
93
|
+
xs: number;
|
|
94
|
+
sm: number;
|
|
95
|
+
md: number;
|
|
96
|
+
lg: number;
|
|
97
|
+
xl: number;
|
|
98
|
+
xxl: number;
|
|
99
|
+
hero: number;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export type Opacity = {
|
|
103
|
+
disabled: number;
|
|
104
|
+
inactive: number;
|
|
105
|
+
subtle: number;
|
|
106
|
+
medium: number;
|
|
107
|
+
full: number;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export type AvatarSizes = {
|
|
111
|
+
xs: number;
|
|
112
|
+
sm: number;
|
|
113
|
+
md: number;
|
|
114
|
+
lg: number;
|
|
115
|
+
xl: number;
|
|
116
|
+
xxl: number;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export type ComponentSizes = {
|
|
120
|
+
touchTarget: number;
|
|
121
|
+
progressBar: {
|
|
122
|
+
normal: number;
|
|
123
|
+
thick: number;
|
|
124
|
+
};
|
|
125
|
+
dot: {
|
|
126
|
+
active: number;
|
|
127
|
+
inactive: number;
|
|
128
|
+
};
|
|
129
|
+
buttonHeight: {
|
|
130
|
+
sm: number;
|
|
131
|
+
md: number;
|
|
132
|
+
lg: number;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type BaseTokens = {
|
|
137
|
+
spacing: Spacing;
|
|
138
|
+
typography: Typography;
|
|
139
|
+
borders: Borders;
|
|
140
|
+
iconSizes: IconSizes;
|
|
141
|
+
opacity: Opacity;
|
|
142
|
+
avatarSizes: AvatarSizes;
|
|
143
|
+
sizes: ComponentSizes;
|
|
144
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BORDER TOKENS
|
|
3
|
+
*
|
|
4
|
+
* Border radius, width, and component-specific border styles
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ViewStyle } from 'react-native';
|
|
8
|
+
import type { Borders } from './BaseTokens';
|
|
9
|
+
|
|
10
|
+
export const borders: Borders = {
|
|
11
|
+
radius: {
|
|
12
|
+
none: 0,
|
|
13
|
+
xs: 2,
|
|
14
|
+
sm: 4,
|
|
15
|
+
md: 8,
|
|
16
|
+
lg: 12,
|
|
17
|
+
xl: 16,
|
|
18
|
+
xxl: 24,
|
|
19
|
+
full: 9999, // TODO: Use DESIGN_CONSTANTS.FULL_BORDER_RADIUS
|
|
20
|
+
},
|
|
21
|
+
width: {
|
|
22
|
+
none: 0,
|
|
23
|
+
thin: 1,
|
|
24
|
+
medium: 2,
|
|
25
|
+
thick: 4,
|
|
26
|
+
},
|
|
27
|
+
button: {
|
|
28
|
+
borderRadius: 12,
|
|
29
|
+
borderWidth: 0,
|
|
30
|
+
} as ViewStyle,
|
|
31
|
+
card: {
|
|
32
|
+
borderRadius: 16,
|
|
33
|
+
borderWidth: 1,
|
|
34
|
+
} as ViewStyle,
|
|
35
|
+
input: {
|
|
36
|
+
borderRadius: 8,
|
|
37
|
+
borderWidth: 1,
|
|
38
|
+
} as ViewStyle,
|
|
39
|
+
pill: {
|
|
40
|
+
borderRadius: 9999,
|
|
41
|
+
borderWidth: 0,
|
|
42
|
+
} as ViewStyle,
|
|
43
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIZE TOKENS
|
|
3
|
+
*
|
|
4
|
+
* Icon sizes, opacity levels, avatar sizes, and component dimensions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { IconSizes, Opacity, AvatarSizes, ComponentSizes } from './BaseTokens';
|
|
8
|
+
|
|
9
|
+
export const iconSizes: IconSizes = {
|
|
10
|
+
xs: 16,
|
|
11
|
+
sm: 20,
|
|
12
|
+
md: 24,
|
|
13
|
+
lg: 32,
|
|
14
|
+
xl: 40,
|
|
15
|
+
xxl: 48,
|
|
16
|
+
hero: 64,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const opacity: Opacity = {
|
|
20
|
+
disabled: 0.6,
|
|
21
|
+
inactive: 0.7,
|
|
22
|
+
subtle: 0.8,
|
|
23
|
+
medium: 0.9,
|
|
24
|
+
full: 1.0,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const avatarSizes: AvatarSizes = {
|
|
28
|
+
xs: 24,
|
|
29
|
+
sm: 32,
|
|
30
|
+
md: 40,
|
|
31
|
+
lg: 48,
|
|
32
|
+
xl: 64,
|
|
33
|
+
xxl: 80,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const sizes: ComponentSizes = {
|
|
37
|
+
touchTarget: 44, // TODO: Use DESIGN_CONSTANTS.MINIMUM_TOUCH_TARGET
|
|
38
|
+
progressBar: {
|
|
39
|
+
normal: 4,
|
|
40
|
+
thick: 8,
|
|
41
|
+
},
|
|
42
|
+
dot: {
|
|
43
|
+
active: 12,
|
|
44
|
+
inactive: 8,
|
|
45
|
+
},
|
|
46
|
+
buttonHeight: {
|
|
47
|
+
sm: 40,
|
|
48
|
+
md: 48,
|
|
49
|
+
lg: 56,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPACING TOKENS
|
|
3
|
+
*
|
|
4
|
+
* Spacing scale and semantic spacing values
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Spacing } from './BaseTokens';
|
|
8
|
+
|
|
9
|
+
export const spacing: Spacing = {
|
|
10
|
+
// Base Spacing Scale (4px base unit)
|
|
11
|
+
xs: 4,
|
|
12
|
+
sm: 8,
|
|
13
|
+
md: 16,
|
|
14
|
+
lg: 24,
|
|
15
|
+
xl: 32,
|
|
16
|
+
xxl: 48,
|
|
17
|
+
xxxl: 64,
|
|
18
|
+
|
|
19
|
+
// Semantic Spacing
|
|
20
|
+
screenPadding: 20,
|
|
21
|
+
cardPadding: 16,
|
|
22
|
+
buttonPadding: 16,
|
|
23
|
+
inputPadding: 12,
|
|
24
|
+
sectionSpacing: 24,
|
|
25
|
+
|
|
26
|
+
// Icon Sizes
|
|
27
|
+
iconSizeSmall: 16,
|
|
28
|
+
iconSizeMedium: 20,
|
|
29
|
+
iconSizeLarge: 24,
|
|
30
|
+
iconSizeXLarge: 32,
|
|
31
|
+
iconSizeHero: 64,
|
|
32
|
+
|
|
33
|
+
// Component Heights
|
|
34
|
+
buttonHeight: 48,
|
|
35
|
+
inputHeight: 48,
|
|
36
|
+
appBarHeight: 56,
|
|
37
|
+
tabBarHeight: 60,
|
|
38
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TYPOGRAPHY TOKENS
|
|
3
|
+
*
|
|
4
|
+
* Typography scale and text styles following Material Design 3
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { TextStyle } from 'react-native';
|
|
8
|
+
import type { Typography } from './BaseTokens';
|
|
9
|
+
|
|
10
|
+
export const typography: Typography = {
|
|
11
|
+
displayLarge: {
|
|
12
|
+
fontSize: 57,
|
|
13
|
+
fontWeight: '400',
|
|
14
|
+
lineHeight: 64,
|
|
15
|
+
letterSpacing: -0.25,
|
|
16
|
+
} as TextStyle,
|
|
17
|
+
displayMedium: {
|
|
18
|
+
fontSize: 45,
|
|
19
|
+
fontWeight: '400',
|
|
20
|
+
lineHeight: 52,
|
|
21
|
+
letterSpacing: 0,
|
|
22
|
+
} as TextStyle,
|
|
23
|
+
displaySmall: {
|
|
24
|
+
fontSize: 36,
|
|
25
|
+
fontWeight: '400',
|
|
26
|
+
lineHeight: 44,
|
|
27
|
+
letterSpacing: 0,
|
|
28
|
+
} as TextStyle,
|
|
29
|
+
headlineLarge: {
|
|
30
|
+
fontSize: 32,
|
|
31
|
+
fontWeight: '400',
|
|
32
|
+
lineHeight: 40,
|
|
33
|
+
letterSpacing: 0,
|
|
34
|
+
} as TextStyle,
|
|
35
|
+
headlineMedium: {
|
|
36
|
+
fontSize: 28,
|
|
37
|
+
fontWeight: '400',
|
|
38
|
+
lineHeight: 36,
|
|
39
|
+
letterSpacing: 0,
|
|
40
|
+
} as TextStyle,
|
|
41
|
+
headlineSmall: {
|
|
42
|
+
fontSize: 24,
|
|
43
|
+
fontWeight: '400',
|
|
44
|
+
lineHeight: 32,
|
|
45
|
+
letterSpacing: 0,
|
|
46
|
+
} as TextStyle,
|
|
47
|
+
titleLarge: {
|
|
48
|
+
fontSize: 22,
|
|
49
|
+
fontWeight: '500',
|
|
50
|
+
lineHeight: 28,
|
|
51
|
+
letterSpacing: 0,
|
|
52
|
+
} as TextStyle,
|
|
53
|
+
titleMedium: {
|
|
54
|
+
fontSize: 16,
|
|
55
|
+
fontWeight: '500',
|
|
56
|
+
lineHeight: 24,
|
|
57
|
+
letterSpacing: 0.15,
|
|
58
|
+
} as TextStyle,
|
|
59
|
+
titleSmall: {
|
|
60
|
+
fontSize: 14,
|
|
61
|
+
fontWeight: '500',
|
|
62
|
+
lineHeight: 20,
|
|
63
|
+
letterSpacing: 0.1,
|
|
64
|
+
} as TextStyle,
|
|
65
|
+
bodyLarge: {
|
|
66
|
+
fontSize: 16,
|
|
67
|
+
fontWeight: '400',
|
|
68
|
+
lineHeight: 24,
|
|
69
|
+
letterSpacing: 0.5,
|
|
70
|
+
} as TextStyle,
|
|
71
|
+
bodyMedium: {
|
|
72
|
+
fontSize: 14,
|
|
73
|
+
fontWeight: '400',
|
|
74
|
+
lineHeight: 20,
|
|
75
|
+
letterSpacing: 0.25,
|
|
76
|
+
} as TextStyle,
|
|
77
|
+
bodySmall: {
|
|
78
|
+
fontSize: 12,
|
|
79
|
+
fontWeight: '400',
|
|
80
|
+
lineHeight: 16,
|
|
81
|
+
letterSpacing: 0.4,
|
|
82
|
+
} as TextStyle,
|
|
83
|
+
labelLarge: {
|
|
84
|
+
fontSize: 14,
|
|
85
|
+
fontWeight: '500',
|
|
86
|
+
lineHeight: 20,
|
|
87
|
+
letterSpacing: 0.1,
|
|
88
|
+
} as TextStyle,
|
|
89
|
+
labelMedium: {
|
|
90
|
+
fontSize: 12,
|
|
91
|
+
fontWeight: '500',
|
|
92
|
+
lineHeight: 16,
|
|
93
|
+
letterSpacing: 0.5,
|
|
94
|
+
} as TextStyle,
|
|
95
|
+
labelSmall: {
|
|
96
|
+
fontSize: 11,
|
|
97
|
+
fontWeight: '500',
|
|
98
|
+
lineHeight: 16,
|
|
99
|
+
letterSpacing: 0.5,
|
|
100
|
+
} as TextStyle,
|
|
101
|
+
button: {
|
|
102
|
+
fontSize: 14,
|
|
103
|
+
fontWeight: '500',
|
|
104
|
+
lineHeight: 20,
|
|
105
|
+
letterSpacing: 0.1,
|
|
106
|
+
} as TextStyle,
|
|
107
|
+
caption: {
|
|
108
|
+
fontSize: 12,
|
|
109
|
+
fontWeight: '400',
|
|
110
|
+
lineHeight: 16,
|
|
111
|
+
letterSpacing: 0.4,
|
|
112
|
+
} as TextStyle,
|
|
113
|
+
overline: {
|
|
114
|
+
fontSize: 10,
|
|
115
|
+
fontWeight: '500',
|
|
116
|
+
lineHeight: 16,
|
|
117
|
+
letterSpacing: 1.5,
|
|
118
|
+
textTransform: 'uppercase',
|
|
119
|
+
} as TextStyle,
|
|
120
|
+
// Legacy compatibility aliases
|
|
121
|
+
headingLarge: {
|
|
122
|
+
fontSize: 32,
|
|
123
|
+
fontWeight: '700',
|
|
124
|
+
lineHeight: 40,
|
|
125
|
+
letterSpacing: 0,
|
|
126
|
+
} as TextStyle,
|
|
127
|
+
headingMedium: {
|
|
128
|
+
fontSize: 24,
|
|
129
|
+
fontWeight: '600',
|
|
130
|
+
lineHeight: 32,
|
|
131
|
+
letterSpacing: 0,
|
|
132
|
+
} as TextStyle,
|
|
133
|
+
headingSmall: {
|
|
134
|
+
fontSize: 20,
|
|
135
|
+
fontWeight: '600',
|
|
136
|
+
lineHeight: 28,
|
|
137
|
+
letterSpacing: 0,
|
|
138
|
+
} as TextStyle,
|
|
139
|
+
// Font weight helpers (for inline fontWeight usage)
|
|
140
|
+
semibold: '600' as const,
|
|
141
|
+
medium: '500' as const,
|
|
142
|
+
bold: '700' as const,
|
|
143
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAppDesignTokens Hook - Theme-Aware Design Tokens
|
|
3
|
+
*
|
|
4
|
+
* ✅ Automatically reads theme from global store
|
|
5
|
+
* ✅ No parameters needed - fully automatic!
|
|
6
|
+
* ✅ Returns tokens for current theme (light/dark)
|
|
7
|
+
* ✅ Single source of truth
|
|
8
|
+
*
|
|
9
|
+
* @example Usage (fully automatic theme-aware)
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { useAppDesignTokens } from '@umituz/react-native-design-system-theme';
|
|
12
|
+
*
|
|
13
|
+
* const MyComponent = () => {
|
|
14
|
+
* const tokens = useAppDesignTokens(); // Automatically uses current theme!
|
|
15
|
+
* return (
|
|
16
|
+
* <View style={{
|
|
17
|
+
* backgroundColor: tokens.colors.primary,
|
|
18
|
+
* padding: tokens.spacing.md
|
|
19
|
+
* }}>
|
|
20
|
+
* <Text style={tokens.typography.bodyLarge}>Hello!</Text>
|
|
21
|
+
* </View>
|
|
22
|
+
* );
|
|
23
|
+
* };
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* How it works:
|
|
27
|
+
* - Reads themeMode from global store (useDesignSystemTheme)
|
|
28
|
+
* - App's theme store syncs to global store automatically
|
|
29
|
+
* - All components get correct tokens without prop drilling
|
|
30
|
+
* - Change theme once, everything updates!
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { useMemo } from 'react';
|
|
34
|
+
import { createDesignTokens, type DesignTokens } from '../core/TokenFactory';
|
|
35
|
+
import { useDesignSystemTheme } from '../infrastructure/globalThemeStore';
|
|
36
|
+
|
|
37
|
+
export const useAppDesignTokens = (): DesignTokens => {
|
|
38
|
+
const { themeMode, customColors } = useDesignSystemTheme();
|
|
39
|
+
|
|
40
|
+
return useMemo(() => {
|
|
41
|
+
const mode = themeMode === 'dark' ? 'dark' : 'light';
|
|
42
|
+
return createDesignTokens(mode, customColors);
|
|
43
|
+
}, [themeMode, customColors]);
|
|
44
|
+
};
|
|
45
|
+
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Styles - Reusable Style Patterns
|
|
3
|
+
*
|
|
4
|
+
* Centralized style utilities to reduce duplication across screens.
|
|
5
|
+
* These styles are composable and follow DRY principles.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { useCommonStyles } from '@umituz/react-native-design-system-theme';
|
|
10
|
+
*
|
|
11
|
+
* const MyComponent = () => {
|
|
12
|
+
* const commonStyles = useCommonStyles();
|
|
13
|
+
* return <View style={commonStyles.screenContainer}>...</View>;
|
|
14
|
+
* };
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { useMemo } from 'react';
|
|
19
|
+
import type { ViewStyle, TextStyle } from 'react-native';
|
|
20
|
+
import { useAppDesignTokens } from './useAppDesignTokens';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hook to get common styles with dynamic theme support
|
|
24
|
+
* Memoized to prevent unnecessary re-renders
|
|
25
|
+
*/
|
|
26
|
+
export const useCommonStyles = () => {
|
|
27
|
+
const tokens = useAppDesignTokens();
|
|
28
|
+
|
|
29
|
+
return useMemo(() => ({
|
|
30
|
+
// ========================================================================
|
|
31
|
+
// SCREEN CONTAINERS
|
|
32
|
+
// ========================================================================
|
|
33
|
+
/**
|
|
34
|
+
* Standard full-screen container
|
|
35
|
+
* Most common pattern: flex: 1 with background color
|
|
36
|
+
*/
|
|
37
|
+
screenContainer: {
|
|
38
|
+
flex: 1,
|
|
39
|
+
backgroundColor: tokens.colors.backgroundPrimary,
|
|
40
|
+
} as ViewStyle,
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Basic flex container without background
|
|
44
|
+
* Use when background is set elsewhere or not needed
|
|
45
|
+
*/
|
|
46
|
+
flexContainer: {
|
|
47
|
+
flex: 1,
|
|
48
|
+
} as ViewStyle,
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Screen container with secondary background
|
|
52
|
+
*/
|
|
53
|
+
screenContainerSecondary: {
|
|
54
|
+
flex: 1,
|
|
55
|
+
backgroundColor: tokens.colors.backgroundSecondary,
|
|
56
|
+
} as ViewStyle,
|
|
57
|
+
|
|
58
|
+
// ========================================================================
|
|
59
|
+
// SCROLL CONTAINERS
|
|
60
|
+
// ========================================================================
|
|
61
|
+
/**
|
|
62
|
+
* Standard ScrollView wrapper
|
|
63
|
+
*/
|
|
64
|
+
scrollView: {
|
|
65
|
+
flex: 1,
|
|
66
|
+
} as ViewStyle,
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* ScrollView content container with standard padding
|
|
70
|
+
*/
|
|
71
|
+
scrollContent: {
|
|
72
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
73
|
+
paddingBottom: tokens.spacing.xl,
|
|
74
|
+
} as ViewStyle,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* ScrollView content that grows to fill available space
|
|
78
|
+
*/
|
|
79
|
+
scrollContentGrow: {
|
|
80
|
+
flexGrow: 1,
|
|
81
|
+
padding: tokens.spacing.lg,
|
|
82
|
+
} as ViewStyle,
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Centered scroll content (for forms, onboarding screens)
|
|
86
|
+
*/
|
|
87
|
+
scrollContentCentered: {
|
|
88
|
+
flexGrow: 1,
|
|
89
|
+
padding: tokens.spacing.lg,
|
|
90
|
+
justifyContent: 'center',
|
|
91
|
+
} as ViewStyle,
|
|
92
|
+
|
|
93
|
+
// ========================================================================
|
|
94
|
+
// LAYOUT UTILITIES
|
|
95
|
+
// ========================================================================
|
|
96
|
+
/**
|
|
97
|
+
* Centered container - both horizontal and vertical
|
|
98
|
+
* Perfect for empty states, splash screens
|
|
99
|
+
*/
|
|
100
|
+
centerContainer: {
|
|
101
|
+
flex: 1,
|
|
102
|
+
justifyContent: 'center',
|
|
103
|
+
alignItems: 'center',
|
|
104
|
+
} as ViewStyle,
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Centered container with padding
|
|
108
|
+
*/
|
|
109
|
+
centerContainerPadded: {
|
|
110
|
+
flex: 1,
|
|
111
|
+
justifyContent: 'center',
|
|
112
|
+
alignItems: 'center',
|
|
113
|
+
paddingHorizontal: tokens.spacing.xl,
|
|
114
|
+
} as ViewStyle,
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Horizontal row layout
|
|
118
|
+
*/
|
|
119
|
+
row: {
|
|
120
|
+
flexDirection: 'row',
|
|
121
|
+
alignItems: 'center',
|
|
122
|
+
} as ViewStyle,
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Horizontal row with space between
|
|
126
|
+
*/
|
|
127
|
+
rowBetween: {
|
|
128
|
+
flexDirection: 'row',
|
|
129
|
+
alignItems: 'center',
|
|
130
|
+
justifyContent: 'space-between',
|
|
131
|
+
} as ViewStyle,
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Horizontal row centered
|
|
135
|
+
*/
|
|
136
|
+
rowCenter: {
|
|
137
|
+
flexDirection: 'row',
|
|
138
|
+
alignItems: 'center',
|
|
139
|
+
justifyContent: 'center',
|
|
140
|
+
} as ViewStyle,
|
|
141
|
+
|
|
142
|
+
// ========================================================================
|
|
143
|
+
// PADDING UTILITIES
|
|
144
|
+
// ========================================================================
|
|
145
|
+
/**
|
|
146
|
+
* Standard horizontal padding
|
|
147
|
+
*/
|
|
148
|
+
paddedHorizontal: {
|
|
149
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
150
|
+
} as ViewStyle,
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Standard vertical padding
|
|
154
|
+
*/
|
|
155
|
+
paddedVertical: {
|
|
156
|
+
paddingVertical: tokens.spacing.lg,
|
|
157
|
+
} as ViewStyle,
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Standard padding all sides
|
|
161
|
+
*/
|
|
162
|
+
padded: {
|
|
163
|
+
padding: tokens.spacing.lg,
|
|
164
|
+
} as ViewStyle,
|
|
165
|
+
|
|
166
|
+
// ========================================================================
|
|
167
|
+
// SECTION STYLES
|
|
168
|
+
// ========================================================================
|
|
169
|
+
/**
|
|
170
|
+
* Standard section container
|
|
171
|
+
*/
|
|
172
|
+
section: {
|
|
173
|
+
marginBottom: tokens.spacing.xl,
|
|
174
|
+
} as ViewStyle,
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Section with padding
|
|
178
|
+
*/
|
|
179
|
+
sectionPadded: {
|
|
180
|
+
marginBottom: tokens.spacing.xl,
|
|
181
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
182
|
+
} as ViewStyle,
|
|
183
|
+
|
|
184
|
+
// ========================================================================
|
|
185
|
+
// TEXT STYLES
|
|
186
|
+
// ========================================================================
|
|
187
|
+
/**
|
|
188
|
+
* Screen title - primary heading
|
|
189
|
+
*/
|
|
190
|
+
screenTitle: {
|
|
191
|
+
...tokens.typography.headingLarge,
|
|
192
|
+
color: tokens.colors.textPrimary,
|
|
193
|
+
marginBottom: tokens.spacing.sm,
|
|
194
|
+
} as TextStyle,
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Section title
|
|
198
|
+
*/
|
|
199
|
+
sectionTitle: {
|
|
200
|
+
...tokens.typography.headingMedium,
|
|
201
|
+
color: tokens.colors.textPrimary,
|
|
202
|
+
marginBottom: tokens.spacing.md,
|
|
203
|
+
} as TextStyle,
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Subtitle/description text
|
|
207
|
+
*/
|
|
208
|
+
subtitle: {
|
|
209
|
+
...tokens.typography.bodyMedium,
|
|
210
|
+
color: tokens.colors.textSecondary,
|
|
211
|
+
textAlign: 'center',
|
|
212
|
+
} as TextStyle,
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Body text
|
|
216
|
+
*/
|
|
217
|
+
bodyText: {
|
|
218
|
+
...tokens.typography.bodyMedium,
|
|
219
|
+
color: tokens.colors.textPrimary,
|
|
220
|
+
} as TextStyle,
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Secondary text (muted)
|
|
224
|
+
*/
|
|
225
|
+
secondaryText: {
|
|
226
|
+
...tokens.typography.bodySmall,
|
|
227
|
+
color: tokens.colors.textSecondary,
|
|
228
|
+
} as TextStyle,
|
|
229
|
+
|
|
230
|
+
// ========================================================================
|
|
231
|
+
// FORM STYLES
|
|
232
|
+
// ========================================================================
|
|
233
|
+
/**
|
|
234
|
+
* Form container
|
|
235
|
+
*/
|
|
236
|
+
form: {
|
|
237
|
+
width: '100%',
|
|
238
|
+
} as ViewStyle,
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Form header section
|
|
242
|
+
*/
|
|
243
|
+
formHeader: {
|
|
244
|
+
alignItems: 'center',
|
|
245
|
+
marginBottom: tokens.spacing.xl,
|
|
246
|
+
} as ViewStyle,
|
|
247
|
+
}), [tokens]);
|
|
248
|
+
};
|