@umituz/react-native-design-system 2.3.1 → 2.3.3

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 (54) hide show
  1. package/package.json +15 -3
  2. package/src/atoms/AtomicInput.tsx +0 -1
  3. package/src/atoms/AtomicPicker.tsx +0 -1
  4. package/src/atoms/picker/components/PickerChips.tsx +0 -1
  5. package/src/atoms/picker/components/PickerModal.tsx +1 -3
  6. package/src/atoms/picker/styles/pickerStyles.ts +1 -1
  7. package/src/{responsive → device/detection}/deviceDetection.ts +7 -7
  8. package/src/device/detection/iPadBreakpoints.ts +55 -0
  9. package/src/device/detection/iPadDetection.ts +48 -0
  10. package/src/device/detection/iPadLayoutUtils.ts +95 -0
  11. package/src/device/detection/iPadModalUtils.ts +98 -0
  12. package/src/device/detection/index.ts +54 -0
  13. package/src/device/domain/entities/Device.ts +207 -0
  14. package/src/device/domain/entities/DeviceMemoryUtils.ts +62 -0
  15. package/src/device/domain/entities/DeviceTypeUtils.ts +66 -0
  16. package/src/device/domain/entities/__tests__/DeviceMemoryUtils.test.ts +118 -0
  17. package/src/device/domain/entities/__tests__/DeviceTypeUtils.test.ts +104 -0
  18. package/src/device/domain/entities/__tests__/DeviceUtils.test.ts +167 -0
  19. package/src/device/index.ts +104 -0
  20. package/src/device/infrastructure/services/ApplicationInfoService.ts +86 -0
  21. package/src/device/infrastructure/services/DeviceCapabilityService.ts +60 -0
  22. package/src/device/infrastructure/services/DeviceIdService.ts +70 -0
  23. package/src/device/infrastructure/services/DeviceInfoService.ts +95 -0
  24. package/src/device/infrastructure/services/DeviceService.ts +104 -0
  25. package/src/device/infrastructure/services/PersistentDeviceIdService.ts +132 -0
  26. package/src/device/infrastructure/services/UserFriendlyIdService.ts +68 -0
  27. package/src/device/infrastructure/utils/__tests__/nativeModuleUtils.test.ts +158 -0
  28. package/src/device/infrastructure/utils/__tests__/stringUtils.test.ts +120 -0
  29. package/src/device/infrastructure/utils/nativeModuleUtils.ts +69 -0
  30. package/src/device/infrastructure/utils/stringUtils.ts +59 -0
  31. package/src/device/presentation/hooks/useAnonymousUser.ts +117 -0
  32. package/src/device/presentation/hooks/useDeviceInfo.ts +222 -0
  33. package/src/molecules/ConfirmationModalContent.tsx +4 -4
  34. package/src/molecules/ConfirmationModalMain.tsx +1 -1
  35. package/src/molecules/ScreenHeader.tsx +2 -2
  36. package/src/molecules/confirmation-modal/components.tsx +1 -1
  37. package/src/molecules/confirmation-modal/styles/confirmationModalStyles.ts +6 -7
  38. package/src/presentation/utils/variants/__tests__/core.test.ts +0 -1
  39. package/src/responsive/gridUtils.ts +1 -1
  40. package/src/responsive/index.ts +36 -20
  41. package/src/responsive/responsive.ts +2 -2
  42. package/src/responsive/responsiveLayout.ts +1 -1
  43. package/src/responsive/responsiveModal.ts +1 -1
  44. package/src/responsive/responsiveSizing.ts +1 -1
  45. package/src/responsive/useResponsive.ts +1 -1
  46. package/src/safe-area/__tests__/components/SafeAreaProvider.test.tsx +2 -2
  47. package/src/safe-area/__tests__/hooks/useContentSafeAreaPadding.test.tsx +2 -2
  48. package/src/safe-area/__tests__/hooks/useHeaderSafeAreaPadding.test.tsx +2 -2
  49. package/src/safe-area/__tests__/hooks/useSafeAreaInsets.test.tsx +2 -2
  50. package/src/safe-area/__tests__/hooks/useStatusBarSafeAreaPadding.test.tsx +2 -2
  51. package/src/safe-area/__tests__/integration/completeFlow.test.tsx +5 -4
  52. package/src/safe-area/__tests__/utils/testUtils.tsx +5 -4
  53. package/src/theme/infrastructure/stores/themeStore.ts +0 -2
  54. package/src/typography/presentation/utils/textColorUtils.ts +0 -1
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Anonymous User Hook
3
+ *
4
+ * Provides persistent device-based user ID for anonymous users.
5
+ * The ID is stable across app restarts and sessions.
6
+ * Compatible with subscription services and Firebase Anonymous Auth.
7
+ *
8
+ * @domain device
9
+ * @layer presentation/hooks
10
+ */
11
+
12
+ import { useState, useEffect, useCallback } from 'react';
13
+ import { PersistentDeviceIdService } from '../../infrastructure/services/PersistentDeviceIdService';
14
+ import { DeviceService } from '../../infrastructure/services/DeviceService';
15
+
16
+ /**
17
+ * Anonymous user data
18
+ */
19
+ export interface AnonymousUser {
20
+ /** Persistent device-based user ID (stable across sessions) */
21
+ userId: string;
22
+ /** User-friendly device name (e.g., "iPhone13-A8F2") */
23
+ deviceName: string;
24
+ /** Display name for the anonymous user */
25
+ displayName: string;
26
+ /** Always true for anonymous users */
27
+ isAnonymous: boolean;
28
+ }
29
+
30
+ /**
31
+ * useAnonymousUser hook options
32
+ */
33
+ export interface UseAnonymousUserOptions {
34
+ /** Custom display name for anonymous user */
35
+ anonymousDisplayName?: string;
36
+ /** Fallback user ID if device ID generation fails */
37
+ fallbackUserId?: string;
38
+ }
39
+
40
+ /**
41
+ * useAnonymousUser hook for persistent device-based user identification
42
+ *
43
+ * USAGE:
44
+ * ```typescript
45
+ * import { useAnonymousUser } from '@umituz/react-native-device';
46
+ *
47
+ * const { anonymousUser, isLoading } = useAnonymousUser();
48
+ *
49
+ * // Use for subscription services
50
+ * await subscriptionService.initialize(anonymousUser?.userId);
51
+ *
52
+ * // Use in SettingsScreen
53
+ * <UserProfileHeader
54
+ * userId={anonymousUser?.userId}
55
+ * displayName={anonymousUser?.displayName}
56
+ * isAnonymous={anonymousUser?.isAnonymous}
57
+ * />
58
+ * ```
59
+ */
60
+ export const useAnonymousUser = (options?: UseAnonymousUserOptions) => {
61
+ const [anonymousUser, setAnonymousUser] = useState<AnonymousUser | null>(null);
62
+ const [isLoading, setIsLoading] = useState(true);
63
+ const [error, setError] = useState<string | null>(null);
64
+
65
+ const {
66
+ anonymousDisplayName = 'Anonymous',
67
+ fallbackUserId = 'anonymous_fallback',
68
+ } = options || {};
69
+
70
+ const loadAnonymousUser = useCallback(async () => {
71
+ setIsLoading(true);
72
+ setError(null);
73
+
74
+ try {
75
+ const [userId, deviceName] = await Promise.all([
76
+ PersistentDeviceIdService.getDeviceId(),
77
+ DeviceService.getUserFriendlyId(),
78
+ ]);
79
+
80
+ setAnonymousUser({
81
+ userId: userId || fallbackUserId,
82
+ deviceName: deviceName || 'Unknown Device',
83
+ displayName: anonymousDisplayName,
84
+ isAnonymous: true,
85
+ });
86
+ } catch {
87
+ setAnonymousUser({
88
+ userId: fallbackUserId,
89
+ deviceName: 'Unknown Device',
90
+ displayName: anonymousDisplayName,
91
+ isAnonymous: true,
92
+ });
93
+ setError('Failed to generate device ID');
94
+ } finally {
95
+ setIsLoading(false);
96
+ }
97
+ }, [anonymousDisplayName, fallbackUserId]);
98
+
99
+ const refresh = useCallback(async () => {
100
+ await loadAnonymousUser();
101
+ }, [loadAnonymousUser]);
102
+
103
+ useEffect(() => {
104
+ loadAnonymousUser();
105
+ }, [loadAnonymousUser]);
106
+
107
+ return {
108
+ /** Anonymous user data with persistent device-based ID */
109
+ anonymousUser,
110
+ /** Loading state */
111
+ isLoading,
112
+ /** Error message if ID generation failed */
113
+ error,
114
+ /** Refresh function to reload user data */
115
+ refresh,
116
+ };
117
+ };
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Device Domain - useDeviceInfo Hook
3
+ *
4
+ * React hook for device and application information.
5
+ * Provides device details with state management.
6
+ *
7
+ * @domain device
8
+ * @layer presentation/hooks
9
+ */
10
+
11
+ import { useState, useEffect, useCallback } from 'react';
12
+ import { DeviceService } from '../../infrastructure/services/DeviceService';
13
+ import type { DeviceInfo, ApplicationInfo, SystemInfo } from '../../domain/entities/Device';
14
+
15
+ /**
16
+ * useDeviceInfo hook for device and application information
17
+ *
18
+ * USAGE:
19
+ * ```typescript
20
+ * const { deviceInfo, appInfo, systemInfo, isLoading, refresh } = useDeviceInfo();
21
+ *
22
+ * // Display device info
23
+ * <Text>Device: {deviceInfo?.modelName}</Text>
24
+ * <Text>OS: {deviceInfo?.osName} {deviceInfo?.osVersion}</Text>
25
+ *
26
+ * // Display app info
27
+ * <Text>App: {appInfo?.applicationName}</Text>
28
+ * <Text>Version: {appInfo?.nativeApplicationVersion}</Text>
29
+ *
30
+ * // Refresh info
31
+ * <AtomicButton onPress={refresh}>Refresh</AtomicButton>
32
+ * ```
33
+ */
34
+ export const useDeviceInfo = () => {
35
+ const [deviceInfo, setDeviceInfo] = useState<DeviceInfo | null>(null);
36
+ const [appInfo, setAppInfo] = useState<ApplicationInfo | null>(null);
37
+ const [systemInfo, setSystemInfo] = useState<SystemInfo | null>(null);
38
+ const [isLoading, setIsLoading] = useState(true);
39
+ const [error, setError] = useState<string | null>(null);
40
+
41
+ /**
42
+ * Load all device and app information
43
+ */
44
+ const loadInfo = useCallback(async () => {
45
+ setIsLoading(true);
46
+ setError(null);
47
+
48
+ try {
49
+ const system = await DeviceService.getSystemInfo();
50
+ setSystemInfo(system);
51
+ setDeviceInfo(system.device);
52
+ setAppInfo(system.application);
53
+ } catch (err) {
54
+ const errorMessage = err instanceof Error ? err.message : 'Failed to load device info';
55
+ setError(errorMessage);
56
+ } finally {
57
+ setIsLoading(false);
58
+ }
59
+ }, []);
60
+
61
+ /**
62
+ * Load device info only
63
+ */
64
+ const loadDeviceInfo = useCallback(async () => {
65
+ setIsLoading(true);
66
+ setError(null);
67
+
68
+ try {
69
+ const info = await DeviceService.getDeviceInfo();
70
+ setDeviceInfo(info);
71
+ } catch (err) {
72
+ const errorMessage = err instanceof Error ? err.message : 'Failed to load device info';
73
+ setError(errorMessage);
74
+ } finally {
75
+ setIsLoading(false);
76
+ }
77
+ }, []);
78
+
79
+ /**
80
+ * Load app info only
81
+ */
82
+ const loadAppInfo = useCallback(async () => {
83
+ setIsLoading(true);
84
+ setError(null);
85
+
86
+ try {
87
+ const info = await DeviceService.getApplicationInfo();
88
+ setAppInfo(info);
89
+ } catch (err) {
90
+ const errorMessage = err instanceof Error ? err.message : 'Failed to load app info';
91
+ setError(errorMessage);
92
+ } finally {
93
+ setIsLoading(false);
94
+ }
95
+ }, []);
96
+
97
+ /**
98
+ * Refresh all info
99
+ */
100
+ const refresh = useCallback(async () => {
101
+ await loadInfo();
102
+ }, [loadInfo]);
103
+
104
+ /**
105
+ * Load info on mount
106
+ */
107
+ useEffect(() => {
108
+ loadInfo();
109
+ }, [loadInfo]);
110
+
111
+ return {
112
+ // Data
113
+ deviceInfo,
114
+ appInfo,
115
+ systemInfo,
116
+
117
+ // State
118
+ isLoading,
119
+ error,
120
+
121
+ // Functions
122
+ refresh,
123
+ loadDeviceInfo,
124
+ loadAppInfo,
125
+ };
126
+ };
127
+
128
+ /**
129
+ * useDeviceCapabilities hook for device feature detection
130
+ *
131
+ * USAGE:
132
+ * ```typescript
133
+ * const { isDevice, isTablet, hasNotch, totalMemoryGB } = useDeviceCapabilities();
134
+ *
135
+ * // Conditional rendering
136
+ * {isTablet && <TabletLayout />}
137
+ * {hasNotch && <NotchSpacer />}
138
+ *
139
+ * // Performance optimization
140
+ * {totalMemoryGB && totalMemoryGB < 2 && <LowMemoryWarning />}
141
+ * ```
142
+ */
143
+ export const useDeviceCapabilities = () => {
144
+ const [isDevice, setIsDevice] = useState(false);
145
+ const [isTablet, setIsTablet] = useState(false);
146
+ const [hasNotch, setHasNotch] = useState(false);
147
+ const [totalMemoryGB, setTotalMemoryGB] = useState<number | null>(null);
148
+ const [isLoading, setIsLoading] = useState(true);
149
+
150
+ useEffect(() => {
151
+ const loadCapabilities = async () => {
152
+ setIsLoading(true);
153
+
154
+ try {
155
+ const capabilities = await DeviceService.getDeviceCapabilities();
156
+ setIsDevice(capabilities.isDevice);
157
+ setIsTablet(capabilities.isTablet);
158
+ setHasNotch(capabilities.hasNotch);
159
+ setTotalMemoryGB(capabilities.totalMemoryGB);
160
+ } catch {
161
+ setIsDevice(false);
162
+ setIsTablet(false);
163
+ setHasNotch(false);
164
+ setTotalMemoryGB(null);
165
+ } finally {
166
+ setIsLoading(false);
167
+ }
168
+ };
169
+
170
+ loadCapabilities();
171
+ }, []);
172
+
173
+ return {
174
+ isDevice,
175
+ isTablet,
176
+ hasNotch,
177
+ totalMemoryGB,
178
+ isLoading,
179
+ };
180
+ };
181
+
182
+ /**
183
+ * useDeviceId hook for device unique identifier
184
+ *
185
+ * WARNING: Use with caution - user privacy considerations!
186
+ *
187
+ * USAGE:
188
+ * ```typescript
189
+ * const { deviceId, isLoading } = useDeviceId();
190
+ *
191
+ * // Analytics, crash reporting (with user consent)
192
+ * if (deviceId) {
193
+ * analytics.setUserId(deviceId);
194
+ * }
195
+ * ```
196
+ */
197
+ export const useDeviceId = () => {
198
+ const [deviceId, setDeviceId] = useState<string | null>(null);
199
+ const [isLoading, setIsLoading] = useState(true);
200
+
201
+ useEffect(() => {
202
+ const loadDeviceId = async () => {
203
+ setIsLoading(true);
204
+
205
+ try {
206
+ const id = await DeviceService.getDeviceId();
207
+ setDeviceId(id);
208
+ } catch {
209
+ setDeviceId(null);
210
+ } finally {
211
+ setIsLoading(false);
212
+ }
213
+ };
214
+
215
+ loadDeviceId();
216
+ }, []);
217
+
218
+ return {
219
+ deviceId,
220
+ isLoading,
221
+ };
222
+ };
@@ -52,13 +52,13 @@ export const ConfirmationModalContent: React.FC<{
52
52
  style?: StyleProp<ViewStyle>;
53
53
  testID: string;
54
54
  }> = ({ tokens, variant, title, message, confirmText, cancelText, icon, onConfirm, onCancel, style, testID }) => {
55
- const variantConfig = getVariantConfig(variant as 'default' | 'destructive' | 'warning' | 'success', tokens);
55
+ const variantConfig = getVariantConfig(variant as 'default' | 'destructive' | 'warning' | 'success');
56
56
  const finalIcon = icon || variantConfig.icon;
57
57
  const getConfirmButtonStyle = useConfirmButtonStyle(variant, tokens);
58
58
 
59
59
  return (
60
60
  <View style={[getModalContainerStyle(tokens), style]}>
61
- <View style={getIconContainerStyle(tokens)}>
61
+ <View style={getIconContainerStyle()}>
62
62
  <ConfirmationModalIcon
63
63
  icon={finalIcon}
64
64
  iconColor={variantConfig.iconColor}
@@ -66,11 +66,11 @@ export const ConfirmationModalContent: React.FC<{
66
66
  />
67
67
  </View>
68
68
 
69
- <View style={getTitleContainerStyle(tokens)}>
69
+ <View style={getTitleContainerStyle()}>
70
70
  <ConfirmationModalTitle title={title} tokens={tokens} testID={testID} />
71
71
  </View>
72
72
 
73
- <View style={getMessageContainerStyle(tokens)}>
73
+ <View style={getMessageContainerStyle()}>
74
74
  <ConfirmationModalMessage message={message} tokens={tokens} testID={testID} />
75
75
  </View>
76
76
 
@@ -65,7 +65,7 @@ export const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
65
65
  statusBarTranslucent
66
66
  testID={testID}
67
67
  >
68
- <View style={getModalOverlayStyle(tokens)}>
68
+ <View style={getModalOverlayStyle()}>
69
69
  <ConfirmationModalBackdrop
70
70
  showBackdrop={showBackdrop}
71
71
  onBackdropPress={handleBackdropPress}
@@ -74,8 +74,8 @@ const ScreenHeaderBackButton: React.FC<{
74
74
  const handleBackPress = React.useCallback(() => {
75
75
  if (onBackPress) {
76
76
  onBackPress();
77
- } else {
78
- __DEV__ && console.warn('ScreenHeader: onBackPress is required when back button is visible');
77
+ } else if (__DEV__) {
78
+ console.warn('ScreenHeader: onBackPress is required when back button is visible');
79
79
  }
80
80
  }, [onBackPress]);
81
81
 
@@ -70,7 +70,7 @@ export const ConfirmationModalButtons: React.FC<{
70
70
  confirmButtonStyle: StyleProp<ViewStyle>;
71
71
  testID: string;
72
72
  }> = ({ confirmText, cancelText, onConfirm, onCancel, confirmButtonStyle, testID }) => (
73
- <View style={getButtonContainerStyle({} as DesignTokens)}>
73
+ <View style={getButtonContainerStyle()}>
74
74
  <AtomicButton
75
75
  variant="outline"
76
76
  size="md"
@@ -13,8 +13,7 @@ import type { DesignTokens } from '../../../theme';
13
13
  * Note: Confirm text is handled in component with translations
14
14
  */
15
15
  export const getVariantConfig = (
16
- variant: ConfirmationModalVariant,
17
- _tokens: DesignTokens
16
+ variant: ConfirmationModalVariant
18
17
  ): Omit<ConfirmationModalVariantConfig, 'confirmText'> => {
19
18
  switch (variant) {
20
19
  case 'destructive':
@@ -44,7 +43,7 @@ export const getVariantConfig = (
44
43
  /**
45
44
  * Get modal overlay style
46
45
  */
47
- export const getModalOverlayStyle = (_tokens: DesignTokens): ViewStyle => ({
46
+ export const getModalOverlayStyle = (): ViewStyle => ({
48
47
  flex: 1,
49
48
  justifyContent: 'center',
50
49
  alignItems: 'center',
@@ -79,28 +78,28 @@ export const getModalContainerStyle = (tokens: DesignTokens): ViewStyle => ({
79
78
  /**
80
79
  * Get icon container style
81
80
  */
82
- export const getIconContainerStyle = (_tokens: DesignTokens): ViewStyle => ({
81
+ export const getIconContainerStyle = (): ViewStyle => ({
83
82
  marginBottom: 16,
84
83
  });
85
84
 
86
85
  /**
87
86
  * Get title container style
88
87
  */
89
- export const getTitleContainerStyle = (_tokens: DesignTokens): ViewStyle => ({
88
+ export const getTitleContainerStyle = (): ViewStyle => ({
90
89
  marginBottom: 8,
91
90
  });
92
91
 
93
92
  /**
94
93
  * Get message container style
95
94
  */
96
- export const getMessageContainerStyle = (_tokens: DesignTokens): ViewStyle => ({
95
+ export const getMessageContainerStyle = (): ViewStyle => ({
97
96
  marginBottom: 24,
98
97
  });
99
98
 
100
99
  /**
101
100
  * Get button container style
102
101
  */
103
- export const getButtonContainerStyle = (_tokens: DesignTokens): ViewStyle => ({
102
+ export const getButtonContainerStyle = (): ViewStyle => ({
104
103
  flexDirection: 'row',
105
104
  gap: 12,
106
105
  width: '100%',
@@ -1,5 +1,4 @@
1
1
  import { describe, it, expect } from '@jest/globals';
2
- import { View, Text } from 'react-native';
3
2
  import { createVariants, type VariantConfig } from '../core';
4
3
 
5
4
  describe('createVariants', () => {
@@ -3,7 +3,7 @@
3
3
  * Responsive grid sizing and column calculations
4
4
  */
5
5
 
6
- import { getScreenDimensions } from './deviceDetection';
6
+ import { getScreenDimensions } from '../device/detection';
7
7
  import { DEVICE_BREAKPOINTS, GRID_CONFIG } from './config';
8
8
  import { validateNumber } from './validation';
9
9
 
@@ -1,24 +1,16 @@
1
1
  /**
2
- * @umituz/react-native-design-system-responsive - Public API
2
+ * @umituz/react-native-design-system/responsive - Public API
3
3
  *
4
- * Responsive design utilities for React Native - Screen dimensions, device detection,
5
- * and responsive sizing utilities following Material Design 3 and iOS HIG principles.
6
- *
7
- * Usage:
8
- * ```typescript
9
- * import { useResponsive, isTablet, getResponsiveLogoSize } from '@umituz/react-native-design-system-responsive';
10
- * ```
4
+ * Responsive sizing and layout utilities for React Native.
5
+ * For device detection, use '@umituz/react-native-design-system/device'.
11
6
  */
12
7
 
13
8
  // Hook exports
14
9
  export { useResponsive } from './useResponsive';
15
10
  export type { UseResponsiveReturn } from './useResponsive';
16
11
 
17
- // Utility function exports
12
+ // Responsive sizing utilities
18
13
  export {
19
- getScreenDimensions,
20
- isSmallPhone,
21
- isTablet,
22
14
  getResponsiveLogoSize,
23
15
  getResponsiveInputHeight,
24
16
  getResponsiveHorizontalPadding,
@@ -43,18 +35,40 @@ export {
43
35
  type GridCellSizeConfig,
44
36
  getResponsiveMaxWidth,
45
37
  getResponsiveFontSize,
46
- isLandscape,
47
- getDeviceType,
48
- DeviceType,
49
38
  MODAL_CONFIG,
50
39
  } from './responsive';
51
40
 
52
- // Device detection exports
53
- export { getSpacingMultiplier } from './deviceDetection';
54
-
55
-
41
+ // Re-export from device for backward compatibility
42
+ export {
43
+ DeviceType,
44
+ getScreenDimensions,
45
+ isSmallPhone,
46
+ isTablet,
47
+ isLandscape,
48
+ getDeviceType,
49
+ getSpacingMultiplier,
50
+ isIPad,
51
+ isIPadMini,
52
+ isIPadPro,
53
+ isIPadLandscape,
54
+ IPAD_BREAKPOINTS,
55
+ TOUCH_TARGETS,
56
+ CONTENT_WIDTH_CONSTRAINTS,
57
+ IPAD_LAYOUT_CONFIG,
58
+ getContentMaxWidth,
59
+ getIPadGridColumns,
60
+ getTouchTargetSize,
61
+ getIPadScreenPadding,
62
+ getIPadFontScale,
63
+ getIPadLayoutInfo,
64
+ type IPadLayoutInfo,
65
+ getIPadModalDimensions,
66
+ getPaywallDimensions,
67
+ type ModalDimensions,
68
+ type PaywallDimensions,
69
+ } from '../device/detection';
56
70
 
57
- // Platform constants exports
71
+ // Platform constants
58
72
  export {
59
73
  IOS_HIG,
60
74
  PLATFORM_CONSTANTS,
@@ -62,3 +76,5 @@ export {
62
76
  getMinTouchTarget,
63
77
  } from './platformConstants';
64
78
 
79
+ // Config exports
80
+ export { DEVICE_BREAKPOINTS } from './config';
@@ -7,7 +7,7 @@
7
7
  * This is the main export file that imports from specialized modules.
8
8
  */
9
9
 
10
- // Device detection
10
+ // Device detection (re-exported from device module)
11
11
  export {
12
12
  getScreenDimensions,
13
13
  isSmallPhone,
@@ -15,7 +15,7 @@ export {
15
15
  isLandscape,
16
16
  getDeviceType,
17
17
  DeviceType,
18
- } from './deviceDetection';
18
+ } from '../device/detection';
19
19
 
20
20
  // Responsive sizing
21
21
  export {
@@ -3,7 +3,7 @@
3
3
  * Layout utilities for positioning and spacing.
4
4
  */
5
5
 
6
- import { getScreenDimensions } from './deviceDetection';
6
+ import { getScreenDimensions } from '../device/detection';
7
7
  import { DEVICE_BREAKPOINTS, LAYOUT_CONSTANTS } from './config';
8
8
  import { validateNumber, validateSafeAreaInsets } from './validation';
9
9
 
@@ -3,7 +3,7 @@
3
3
  * Modal, bottom sheet, and dialog layout utilities.
4
4
  */
5
5
 
6
- import { getScreenDimensions } from './deviceDetection';
6
+ import { getScreenDimensions } from '../device/detection';
7
7
  import {
8
8
  DEVICE_BREAKPOINTS,
9
9
  LAYOUT_CONSTANTS,
@@ -3,7 +3,7 @@
3
3
  * Responsive sizing utilities for UI components.
4
4
  */
5
5
 
6
- import { getScreenDimensions } from './deviceDetection';
6
+ import { getScreenDimensions } from '../device/detection';
7
7
  import {
8
8
  DEVICE_BREAKPOINTS,
9
9
  RESPONSIVE_PERCENTAGES,
@@ -38,7 +38,7 @@ import {
38
38
  type ResponsiveBottomSheetLayout,
39
39
  type ResponsiveDialogLayout,
40
40
  } from './responsive';
41
- import { getSpacingMultiplier } from './deviceDetection';
41
+ import { getSpacingMultiplier } from '../device/detection';
42
42
 
43
43
  export interface UseResponsiveReturn {
44
44
  // Device info
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Tests for SafeAreaProvider component
3
3
  */
4
+ import { describe, it, expect } from '@jest/globals';
5
+ import { SafeAreaProvider, useSafeAreaConfig } from '../../components/SafeAreaProvider';
4
6
 
5
7
  describe('SafeAreaProvider', () => {
6
8
  it('should be defined', () => {
7
- const { SafeAreaProvider } = require('../../components/SafeAreaProvider');
8
9
  expect(SafeAreaProvider).toBeDefined();
9
10
  });
10
11
 
11
12
  it('should have useSafeAreaConfig export', () => {
12
- const { useSafeAreaConfig } = require('../../components/SafeAreaProvider');
13
13
  expect(useSafeAreaConfig).toBeDefined();
14
14
  });
15
15
  });
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Tests for useContentSafeAreaPadding hook
3
3
  */
4
+ import { describe, it, expect } from '@jest/globals';
5
+ import { useContentSafeAreaPadding } from '../../hooks/useContentSafeAreaPadding';
4
6
 
5
7
  describe('useContentSafeAreaPadding', () => {
6
8
  it('should be defined', () => {
7
- const { useContentSafeAreaPadding } = require('../../hooks/useContentSafeAreaPadding');
8
9
  expect(useContentSafeAreaPadding).toBeDefined();
9
10
  });
10
11
 
11
12
  it('should return function', () => {
12
- const { useContentSafeAreaPadding } = require('../../hooks/useContentSafeAreaPadding');
13
13
  expect(typeof useContentSafeAreaPadding).toBe('function');
14
14
  });
15
15
  });
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Tests for useHeaderSafeAreaPadding hook
3
3
  */
4
+ import { describe, it, expect } from '@jest/globals';
5
+ import { useHeaderSafeAreaPadding } from '../../hooks/useHeaderSafeAreaPadding';
4
6
 
5
7
  describe('useHeaderSafeAreaPadding', () => {
6
8
  it('should be defined', () => {
7
- const { useHeaderSafeAreaPadding } = require('../../hooks/useHeaderSafeAreaPadding');
8
9
  expect(useHeaderSafeAreaPadding).toBeDefined();
9
10
  });
10
11
 
11
12
  it('should return function', () => {
12
- const { useHeaderSafeAreaPadding } = require('../../hooks/useHeaderSafeAreaPadding');
13
13
  expect(typeof useHeaderSafeAreaPadding).toBe('function');
14
14
  });
15
15
  });
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Tests for useSafeAreaInsets hook
3
3
  */
4
+ import { describe, it, expect } from '@jest/globals';
5
+ import { useSafeAreaInsets } from '../../hooks/useSafeAreaInsets';
4
6
 
5
7
  describe('useSafeAreaInsets', () => {
6
8
  it('should be defined', () => {
7
- const { useSafeAreaInsets } = require('../../hooks/useSafeAreaInsets');
8
9
  expect(useSafeAreaInsets).toBeDefined();
9
10
  });
10
11
 
11
12
  it('should return function', () => {
12
- const { useSafeAreaInsets } = require('../../hooks/useSafeAreaInsets');
13
13
  expect(typeof useSafeAreaInsets).toBe('function');
14
14
  });
15
15
  });