@umituz/react-native-design-system 4.28.11 → 4.28.13

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.
Files changed (49) hide show
  1. package/package.json +31 -8
  2. package/src/atoms/AtomicAvatar.tsx +69 -40
  3. package/src/atoms/AtomicDatePicker.tsx +6 -6
  4. package/src/atoms/AtomicSpinner.tsx +24 -22
  5. package/src/atoms/AtomicText.tsx +32 -27
  6. package/src/atoms/AtomicTextArea.tsx +17 -15
  7. package/src/atoms/EmptyState.tsx +44 -41
  8. package/src/atoms/button/AtomicButton.tsx +8 -9
  9. package/src/atoms/card/AtomicCard.tsx +26 -8
  10. package/src/atoms/datepicker/components/DatePickerButton.tsx +8 -8
  11. package/src/atoms/datepicker/components/DatePickerModal.tsx +7 -7
  12. package/src/atoms/fab/styles/fabStyles.ts +0 -21
  13. package/src/atoms/icon/index.ts +6 -20
  14. package/src/atoms/picker/components/PickerModal.tsx +24 -4
  15. package/src/atoms/skeleton/AtomicSkeleton.tsx +9 -11
  16. package/src/carousel/Carousel.tsx +43 -20
  17. package/src/carousel/carouselCalculations.ts +12 -9
  18. package/src/carousel/index.ts +0 -1
  19. package/src/device/detection/iPadDetection.ts +5 -14
  20. package/src/device/infrastructure/services/DeviceFeatureService.ts +89 -9
  21. package/src/device/infrastructure/services/DeviceInfoService.ts +33 -0
  22. package/src/device/infrastructure/services/UserFriendlyIdService.ts +8 -6
  23. package/src/device/infrastructure/utils/__tests__/stringUtils.test.ts +56 -20
  24. package/src/device/infrastructure/utils/nativeModuleUtils.ts +16 -2
  25. package/src/device/infrastructure/utils/stringUtils.ts +51 -5
  26. package/src/filesystem/domain/utils/FileUtils.ts +5 -1
  27. package/src/image/domain/utils/ImageUtils.ts +6 -0
  28. package/src/layouts/AppHeader/AppHeader.tsx +13 -3
  29. package/src/layouts/Container/Container.tsx +19 -1
  30. package/src/layouts/FormLayout/FormLayout.tsx +20 -1
  31. package/src/layouts/Grid/Grid.tsx +34 -4
  32. package/src/layouts/ScreenHeader/ScreenHeader.tsx +4 -0
  33. package/src/layouts/ScreenLayout/ScreenLayout.tsx +42 -3
  34. package/src/molecules/SearchBar/SearchBar.tsx +27 -23
  35. package/src/molecules/action-footer/ActionFooter.tsx +32 -31
  36. package/src/molecules/alerts/AlertService.ts +60 -15
  37. package/src/molecules/avatar/Avatar.tsx +3 -3
  38. package/src/molecules/avatar/AvatarGroup.tsx +7 -7
  39. package/src/molecules/bottom-sheet/components/BottomSheet.tsx +3 -3
  40. package/src/molecules/calendar/infrastructure/utils/DateUtilities.ts +12 -1
  41. package/src/molecules/calendar/presentation/components/CalendarDayCell.tsx +48 -32
  42. package/src/molecules/info-grid/InfoGrid.tsx +5 -3
  43. package/src/organisms/FormContainer.tsx +11 -1
  44. package/src/tanstack/domain/utils/ErrorHelpers.ts +2 -2
  45. package/src/tanstack/domain/utils/MetricsCalculator.ts +6 -1
  46. package/src/theme/core/colors/ColorUtils.ts +7 -4
  47. package/src/utils/formatters/stringFormatter.ts +18 -3
  48. package/src/utils/index.ts +6 -4
  49. package/src/utils/math/CalculationUtils.ts +10 -1
@@ -97,6 +97,9 @@ export const FormContainer: React.FC<FormContainerProps> = ({
97
97
  showsVerticalScrollIndicator = false,
98
98
  testID,
99
99
  showBorder = true,
100
+ accessibilityLabel,
101
+ accessibilityHint,
102
+ accessible,
100
103
  }) => {
101
104
  const tokens = useAppDesignTokens();
102
105
  const insets = useSafeAreaInsets();
@@ -138,7 +141,14 @@ export const FormContainer: React.FC<FormContainerProps> = ({
138
141
  );
139
142
 
140
143
  return (
141
- <View style={[styles.container, containerStyle]} testID={testID}>
144
+ <View
145
+ style={[styles.container, containerStyle]}
146
+ testID={testID}
147
+ accessibilityLabel={accessibilityLabel}
148
+ accessibilityHint={accessibilityHint}
149
+ accessible={accessible !== false}
150
+ accessibilityRole="form"
151
+ >
142
152
  <View style={styles.surface}>
143
153
  <ScrollView
144
154
  style={styles.scrollView}
@@ -146,8 +146,8 @@ export function getErrorCode(error: unknown): string | null {
146
146
  /**
147
147
  * Log error in development
148
148
  */
149
- export function logError(_context: string, _error: unknown): void {
149
+ export function logError(context: string, error: unknown): void {
150
150
  if (__DEV__) {
151
-
151
+ console.error(`[${context}]`, error);
152
152
  }
153
153
  }
@@ -22,7 +22,12 @@ export class MetricsCalculator {
22
22
  * Calculates fetch time for a query
23
23
  */
24
24
  static calculateFetchTime(query: Query): number {
25
- return Date.now() - (query.state.dataUpdatedAt ?? Date.now());
25
+ const now = Date.now();
26
+ const updatedAt = query.state.dataUpdatedAt ?? now;
27
+ const fetchTime = now - updatedAt;
28
+
29
+ // Ensure non-negative (handles cases where dataUpdatedAt is in the future)
30
+ return Math.max(0, fetchTime);
26
31
  }
27
32
 
28
33
  /**
@@ -34,10 +34,13 @@ export const withAlpha = (hexColor: string, alpha: number): string => {
34
34
  return hexColor;
35
35
  }
36
36
 
37
- // Convert 3-digit hex to 6-digit
38
- const hex = hexColor.length === 4
39
- ? hexColor.split('').map(c => c + c).join('')
40
- : hexColor;
37
+ let hex = hexColor;
38
+
39
+ // Convert 3-digit hex to 6-digit (e.g., #RGB #RRGGBB)
40
+ if (hex.length === 4) {
41
+ // Remove # and double each character, then add # back
42
+ hex = '#' + hex.slice(1).split('').map(c => c + c).join('');
43
+ }
41
44
 
42
45
  const alphaHex = Math.round(alpha * 255)
43
46
  .toString(16)
@@ -22,10 +22,19 @@ export function formatFileSize(bytes: number, options: FileSizeFormatOptions = {
22
22
  const { decimals = 1, locale = 'en-US' } = options;
23
23
 
24
24
  if (bytes === 0) return '0 Bytes';
25
+ if (bytes < 0) {
26
+ if (__DEV__) {
27
+ console.warn(`[formatFileSize] File size cannot be negative (received: ${bytes}), treating as 0`);
28
+ }
29
+ return '0 Bytes';
30
+ }
25
31
 
26
32
  const k = 1024;
27
- const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
28
- const i = Math.floor(Math.log(bytes) / Math.log(k));
33
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']; // Added EB for safety
34
+ const i = Math.min(
35
+ Math.floor(Math.log(bytes) / Math.log(k)),
36
+ sizes.length - 1 // Prevent array out of bounds
37
+ );
29
38
 
30
39
  return `${formatNumber(bytes / Math.pow(k, i), { decimals, locale })} ${sizes[i]}`;
31
40
  }
@@ -130,10 +139,16 @@ export function formatPhone(phone: string, options: PhoneFormatOptions = {}): st
130
139
  * @returns Truncated text
131
140
  */
132
141
  export function truncateText(text: string, maxLength: number, suffix: string = '...'): string {
133
- if (!text || text.length <= maxLength) {
142
+ if (!text) return '';
143
+ if (text.length <= maxLength) {
134
144
  return text;
135
145
  }
136
146
 
147
+ // Ensure we don't end up with negative slice length
148
+ if (maxLength <= suffix.length) {
149
+ return suffix.slice(0, maxLength);
150
+ }
151
+
137
152
  return text.slice(0, maxLength - suffix.length) + suffix;
138
153
  }
139
154
 
@@ -118,10 +118,9 @@ export {
118
118
  type AsyncOperationState,
119
119
  type AsyncOperationActions,
120
120
  type AsyncOperationReturn,
121
+ type ErrorHandler as AsyncErrorHandler,
121
122
  } from './hooks';
122
123
 
123
- export type { ErrorHandler as AsyncErrorHandler } from './hooks';
124
-
125
124
  // =============================================================================
126
125
  // ERROR HANDLING
127
126
  // =============================================================================
@@ -130,8 +129,11 @@ export {
130
129
  DesignSystemError,
131
130
  ErrorCodes,
132
131
  ErrorCategory,
133
- type ErrorCode,
134
- type ErrorMetadata,
132
+ } from './errors';
133
+
134
+ export type {
135
+ ErrorCode,
136
+ ErrorMetadata,
135
137
  } from './errors';
136
138
 
137
139
  export { ErrorHandler } from './errors/ErrorHandler';
@@ -109,5 +109,14 @@ export function mapRange(
109
109
  outMin: number,
110
110
  outMax: number
111
111
  ): number {
112
- return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
112
+ const range = inMax - inMin;
113
+ if (range === 0) {
114
+ // When input range is zero, return output minimum
115
+ // This prevents division by zero (Infinity/NaN)
116
+ if (__DEV__) {
117
+ console.warn(`[mapRange] Input range is zero (inMin=${inMin}, inMax=${inMax}), returning outMin=${outMin}`);
118
+ }
119
+ return outMin;
120
+ }
121
+ return ((value - inMin) * (outMax - outMin)) / range + outMin;
113
122
  }