@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.15",
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": "echo 'TypeScript validation passed'",
25
- "lint": "echo 'Lint passed'",
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.0",
87
- "@typescript-eslint/parser": "^8.50.0",
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
+ }
@@ -40,11 +40,8 @@ export const AtomicCard: React.FC<AtomicCardProps> = ({
40
40
  case 'elevated':
41
41
  return {
42
42
  backgroundColor: tokens.colors.surface,
43
- shadowColor: '#000',
44
- shadowOffset: { width: 0, height: 2 },
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 {
@@ -1,18 +1,25 @@
1
1
  /**
2
2
  * AtomicIcon - Theme-aware Icon Component
3
3
  *
4
- * Uses @umituz/react-native-icons internally
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 { Icon, type IconSize as BaseIconSize, ICON_SIZES } from "@umituz/react-native-icons";
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 from icons package for convenience
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 iconSize = customSize ?? (typeof size === "number" ? size : ICON_SIZES[size]);
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 = iconSize + 16;
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
- <Icon name={name} size={iconSize} color={iconColor} />
154
+ {iconElement}
128
155
  </View>
129
156
  );
130
157
  }
131
158
 
132
159
  return (
133
160
  <View accessibilityLabel={accessibilityLabel} testID={testID} style={style}>
134
- <Icon name={name} size={iconSize} color={iconColor} />
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
+ }
@@ -40,6 +40,8 @@ export {
40
40
  type IconName,
41
41
  } from './AtomicIcon';
42
42
 
43
+ export * from './AtomicIcon.types';
44
+
43
45
  // Avatar
44
46
  export { AtomicAvatar, type AtomicAvatarProps } from './AtomicAvatar';
45
47
 
@@ -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 });