@umituz/react-native-design-system 2.0.15 → 2.1.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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive and safe area utilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"./package.json": "./package.json"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"typecheck": "
|
|
25
|
-
"lint": "
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"lint": "eslint . --ext .ts,.tsx",
|
|
26
26
|
"version:patch": "npm version patch -m 'chore: release v%s'",
|
|
27
27
|
"version:minor": "npm version minor -m 'chore: release v%s'",
|
|
28
28
|
"version:major": "npm version major -m 'chore: release v%s'"
|
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"@react-native-async-storage/async-storage": ">=2.0.0",
|
|
54
54
|
"@react-native-community/datetimepicker": ">=8.0.0",
|
|
55
55
|
"@react-navigation/native": ">=6.0.0",
|
|
56
|
-
"@umituz/react-native-icons": "latest",
|
|
57
56
|
"expo-linear-gradient": ">=15.0.0",
|
|
58
57
|
"react": ">=19.0.0",
|
|
59
58
|
"react-native": ">=0.81.0",
|
|
@@ -83,12 +82,12 @@
|
|
|
83
82
|
"@react-navigation/native": "^6.0.0",
|
|
84
83
|
"@types/jest": "^30.0.0",
|
|
85
84
|
"@types/react": "~19.1.10",
|
|
86
|
-
"@typescript-eslint/eslint-plugin": "^8.50.
|
|
87
|
-
"@typescript-eslint/parser": "^8.50.
|
|
88
|
-
"@umituz/react-native-icons": "latest",
|
|
85
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
86
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
89
87
|
"eslint": "^9.39.2",
|
|
90
88
|
"eslint-plugin-react": "^7.37.5",
|
|
91
89
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
90
|
+
"eslint-plugin-react-native": "^5.0.0",
|
|
92
91
|
"react": "19.1.0",
|
|
93
92
|
"react-native": "0.81.5",
|
|
94
93
|
"react-native-gesture-handler": "^2.20.0",
|
|
@@ -106,4 +105,4 @@
|
|
|
106
105
|
"README.md",
|
|
107
106
|
"LICENSE"
|
|
108
107
|
]
|
|
109
|
-
}
|
|
108
|
+
}
|
package/src/atoms/AtomicCard.tsx
CHANGED
|
@@ -40,11 +40,8 @@ export const AtomicCard: React.FC<AtomicCardProps> = ({
|
|
|
40
40
|
case 'elevated':
|
|
41
41
|
return {
|
|
42
42
|
backgroundColor: tokens.colors.surface,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
shadowOpacity: 0.1,
|
|
46
|
-
shadowRadius: 4,
|
|
47
|
-
elevation: 2,
|
|
43
|
+
borderWidth: 1,
|
|
44
|
+
borderColor: tokens.colors.outlineVariant || tokens.colors.outline,
|
|
48
45
|
};
|
|
49
46
|
case 'outlined':
|
|
50
47
|
return {
|
package/src/atoms/AtomicIcon.tsx
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AtomicIcon - Theme-aware Icon Component
|
|
3
3
|
*
|
|
4
|
-
* Uses @
|
|
4
|
+
* Uses @expo/vector-icons/Ionicons internally
|
|
5
5
|
* Adds theme-aware semantic colors and background support
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
import { View, StyleSheet, StyleProp, ViewStyle } from "react-native";
|
|
10
|
-
import {
|
|
10
|
+
import { Ionicons } from "@expo/vector-icons";
|
|
11
11
|
import { useAppDesignTokens } from '../theme';
|
|
12
|
+
import {
|
|
13
|
+
getIconSize,
|
|
14
|
+
ICON_SIZES,
|
|
15
|
+
type IconSize as BaseIconSize
|
|
16
|
+
} from "./AtomicIcon.types";
|
|
12
17
|
|
|
13
|
-
// Re-export IconSize
|
|
18
|
+
// Re-export IconSize for convenience
|
|
14
19
|
export type IconSize = BaseIconSize;
|
|
15
20
|
|
|
21
|
+
const FALLBACK_ICON = "help-circle-outline";
|
|
22
|
+
|
|
16
23
|
// Semantic color names that map to theme tokens
|
|
17
24
|
export type IconColor =
|
|
18
25
|
| "primary"
|
|
@@ -96,7 +103,7 @@ export const AtomicIcon: React.FC<AtomicIconProps> = React.memo(({
|
|
|
96
103
|
const tokens = useAppDesignTokens();
|
|
97
104
|
|
|
98
105
|
// Calculate size
|
|
99
|
-
const
|
|
106
|
+
const sizeInPixels = customSize ?? getIconSize(size);
|
|
100
107
|
|
|
101
108
|
// Calculate color
|
|
102
109
|
const iconColor = customColor
|
|
@@ -105,9 +112,29 @@ export const AtomicIcon: React.FC<AtomicIconProps> = React.memo(({
|
|
|
105
112
|
? getSemanticColor(color, tokens)
|
|
106
113
|
: tokens.colors.textPrimary;
|
|
107
114
|
|
|
115
|
+
// Validate icon
|
|
116
|
+
const isValidIcon = name in Ionicons.glyphMap;
|
|
117
|
+
const iconName = isValidIcon ? name : FALLBACK_ICON;
|
|
118
|
+
|
|
119
|
+
if (__DEV__ && !isValidIcon) {
|
|
120
|
+
console.warn(
|
|
121
|
+
`[AtomicIcon] Invalid icon name: "${name}". Using fallback icon "${FALLBACK_ICON}". ` +
|
|
122
|
+
`Available icons: https://icons.expo.fyi/`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const iconElement = (
|
|
127
|
+
<Ionicons
|
|
128
|
+
name={iconName as keyof typeof Ionicons.glyphMap}
|
|
129
|
+
size={sizeInPixels}
|
|
130
|
+
color={iconColor}
|
|
131
|
+
testID={testID ? `${testID}-icon` : undefined}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
|
|
108
135
|
if (withBackground) {
|
|
109
136
|
const bgColor = backgroundColor || tokens.colors.surfaceVariant;
|
|
110
|
-
const containerSize =
|
|
137
|
+
const containerSize = sizeInPixels + 16;
|
|
111
138
|
|
|
112
139
|
return (
|
|
113
140
|
<View
|
|
@@ -124,14 +151,14 @@ export const AtomicIcon: React.FC<AtomicIconProps> = React.memo(({
|
|
|
124
151
|
testID={testID}
|
|
125
152
|
accessibilityLabel={accessibilityLabel}
|
|
126
153
|
>
|
|
127
|
-
|
|
154
|
+
{iconElement}
|
|
128
155
|
</View>
|
|
129
156
|
);
|
|
130
157
|
}
|
|
131
158
|
|
|
132
159
|
return (
|
|
133
160
|
<View accessibilityLabel={accessibilityLabel} testID={testID} style={style}>
|
|
134
|
-
|
|
161
|
+
{iconElement}
|
|
135
162
|
</View>
|
|
136
163
|
);
|
|
137
164
|
});
|
|
@@ -147,3 +174,4 @@ const styles = StyleSheet.create({
|
|
|
147
174
|
|
|
148
175
|
// Legacy type alias for backward compatibility
|
|
149
176
|
export type IconProps = AtomicIconProps;
|
|
177
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon Type Definitions
|
|
3
|
+
* Centralized icon types for @expo/vector-icons Ionicons
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Ionicons } from "@expo/vector-icons";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* All available Ionicons names (type-safe)
|
|
10
|
+
*/
|
|
11
|
+
export type IoniconsName = keyof typeof Ionicons.glyphMap;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Semantic icon size presets
|
|
15
|
+
*/
|
|
16
|
+
export type IconSizePreset = "xs" | "sm" | "md" | "lg" | "xl" | "xxl";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Icon size - preset name or custom number in pixels
|
|
20
|
+
*/
|
|
21
|
+
export type IconSize = IconSizePreset | number;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Icon size mapping to pixels
|
|
25
|
+
*/
|
|
26
|
+
export const ICON_SIZES: Record<IconSizePreset, number> = {
|
|
27
|
+
xs: 12,
|
|
28
|
+
sm: 16,
|
|
29
|
+
md: 20,
|
|
30
|
+
lg: 24,
|
|
31
|
+
xl: 32,
|
|
32
|
+
xxl: 48,
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get icon size in pixels
|
|
37
|
+
*/
|
|
38
|
+
export function getIconSize(size: IconSize): number {
|
|
39
|
+
if (typeof size === "number") return size;
|
|
40
|
+
return ICON_SIZES[size];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Check if size is a preset
|
|
45
|
+
*/
|
|
46
|
+
export function isIconSizePreset(size: IconSize): size is IconSizePreset {
|
|
47
|
+
return typeof size === "string" && size in ICON_SIZES;
|
|
48
|
+
}
|
package/src/atoms/index.ts
CHANGED
|
@@ -29,7 +29,7 @@ const useConfirmButtonStyle = (
|
|
|
29
29
|
) => {
|
|
30
30
|
return React.useCallback(() => {
|
|
31
31
|
const baseStyle = getButtonStyle();
|
|
32
|
-
const variantStyles = [];
|
|
32
|
+
const variantStyles: ViewStyle[] = [];
|
|
33
33
|
|
|
34
34
|
if (variant === 'destructive') variantStyles.push({ backgroundColor: tokens.colors.error });
|
|
35
35
|
if (variant === 'warning') variantStyles.push({ backgroundColor: tokens.colors.warning });
|