@umituz/react-native-design-system 2.6.61 → 2.6.64
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 +1 -1
- package/src/atoms/AtomicButton.tsx +6 -257
- package/src/atoms/AtomicChip.tsx +4 -224
- package/src/atoms/AtomicIcon.tsx +2 -6
- package/src/atoms/AtomicIcon.types.ts +5 -0
- package/src/atoms/AtomicInput.tsx +34 -154
- package/src/atoms/AtomicPicker.tsx +31 -123
- package/src/atoms/button/AtomicButton.tsx +108 -0
- package/src/atoms/button/configs/buttonSizeConfig.ts +37 -0
- package/src/atoms/button/index.ts +6 -0
- package/src/atoms/button/styles/buttonStyles.ts +36 -0
- package/src/atoms/button/styles/buttonVariantStyles.ts +88 -0
- package/src/atoms/button/types/index.ts +40 -0
- package/src/atoms/chip/AtomicChip.tsx +112 -0
- package/src/atoms/chip/configs/chipColorConfig.ts +47 -0
- package/src/atoms/chip/configs/chipSizeConfig.ts +34 -0
- package/src/atoms/chip/index.ts +6 -0
- package/src/atoms/chip/styles/chipStyles.ts +28 -0
- package/src/atoms/chip/types/index.ts +42 -0
- package/src/atoms/index.ts +6 -4
- package/src/atoms/input/components/InputHelper.tsx +49 -0
- package/src/atoms/input/components/InputIcon.tsx +44 -0
- package/src/atoms/input/components/InputLabel.tsx +20 -0
- package/src/atoms/input/styles/inputStylesHelper.ts +1 -1
- package/src/atoms/input/types.ts +72 -0
- package/src/atoms/picker/hooks/usePickerState.ts +139 -0
- package/src/exports/atoms.ts +69 -0
- package/src/exports/device.ts +58 -0
- package/src/exports/layouts.ts +19 -0
- package/src/exports/molecules.ts +166 -0
- package/src/exports/organisms.ts +9 -0
- package/src/exports/responsive.ts +36 -0
- package/src/exports/safe-area.ts +6 -0
- package/src/exports/theme.ts +47 -0
- package/src/exports/typography.ts +22 -0
- package/src/exports/utilities.ts +6 -0
- package/src/exports/variants.ts +22 -0
- package/src/index.ts +11 -417
- package/src/layouts/ScreenLayout/ScreenLayout.tsx +17 -181
- package/src/layouts/ScreenLayout/components/ContentWrapper.tsx +31 -0
- package/src/layouts/ScreenLayout/components/index.ts +6 -0
- package/src/layouts/ScreenLayout/styles/screenLayoutStyles.ts +47 -0
- package/src/layouts/ScreenLayout/types/index.ts +27 -0
- package/src/molecules/avatar/Avatar.constants.ts +103 -0
- package/src/molecules/avatar/Avatar.types.ts +64 -0
- package/src/molecules/avatar/Avatar.utils.ts +8 -160
- package/src/molecules/calendar/index.ts +4 -9
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts +103 -302
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts.bak +116 -0
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.types.ts +64 -0
- package/src/molecules/calendar/infrastructure/storage/CalendarStore.utils.ts +56 -0
- package/src/molecules/calendar/infrastructure/storage/EventActions.ts +140 -0
- package/src/molecules/calendar/infrastructure/storage/NavigationActions.ts +118 -0
- package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +34 -0
- package/src/molecules/calendar/infrastructure/stores/useCalendarEvents.ts +168 -0
- package/src/molecules/calendar/infrastructure/stores/useCalendarNavigation.ts +47 -0
- package/src/molecules/calendar/infrastructure/stores/useCalendarView.ts +24 -0
- package/src/molecules/calendar/presentation/hooks/useCalendar.ts +7 -11
- package/src/responsive/compute/computeDeviceInfo.ts +22 -0
- package/src/responsive/compute/computeResponsivePositioning.ts +42 -0
- package/src/responsive/compute/computeResponsiveSizes.ts +48 -0
- package/src/responsive/padding/paddingUtils.ts +65 -0
- package/src/responsive/positioning/positioningUtils.ts +61 -0
- package/src/responsive/responsiveLayout.ts +11 -264
- package/src/responsive/screen/screenLayoutConfig.ts +38 -0
- package/src/responsive/tabbar/tabBarConfig.ts +88 -0
- package/src/responsive/types/responsiveTypes.ts +69 -0
- package/src/responsive/useResponsive.ts +69 -158
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Padding Utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isTablet, isSmallPhone, getSpacingMultiplier } from '../../device/detection';
|
|
6
|
+
import { LAYOUT_CONSTANTS } from '../config';
|
|
7
|
+
import { validateNumber, validateSafeAreaInsets } from '../validation';
|
|
8
|
+
|
|
9
|
+
export const getResponsiveVerticalPadding = (
|
|
10
|
+
insets: { top?: number; bottom?: number } = { top: 0, bottom: 0 }
|
|
11
|
+
): number => {
|
|
12
|
+
try {
|
|
13
|
+
validateSafeAreaInsets(insets);
|
|
14
|
+
const { top = 0 } = insets;
|
|
15
|
+
const isTabletDevice = isTablet();
|
|
16
|
+
const isSmall = isSmallPhone();
|
|
17
|
+
const spacingMultiplier = getSpacingMultiplier();
|
|
18
|
+
|
|
19
|
+
// Base padding adjusted by device type
|
|
20
|
+
let basePadding: number = LAYOUT_CONSTANTS.VERTICAL_PADDING_STANDARD;
|
|
21
|
+
if (isTabletDevice) {
|
|
22
|
+
basePadding = LAYOUT_CONSTANTS.VERTICAL_PADDING_TABLET;
|
|
23
|
+
} else if (isSmall) {
|
|
24
|
+
basePadding = LAYOUT_CONSTANTS.VERTICAL_PADDING_SMALL;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Apply spacing multiplier for consistency
|
|
28
|
+
const adjustedPadding = basePadding * spacingMultiplier;
|
|
29
|
+
|
|
30
|
+
// Ensure minimum padding respects safe area
|
|
31
|
+
return Math.max(adjustedPadding, top > 0 ? 8 : adjustedPadding);
|
|
32
|
+
} catch {
|
|
33
|
+
return LAYOUT_CONSTANTS.VERTICAL_PADDING_STANDARD;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const getResponsiveHorizontalPadding = (
|
|
38
|
+
basePadding: number = LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE,
|
|
39
|
+
insets: { left?: number; right?: number } = { left: 0, right: 0 }
|
|
40
|
+
): number => {
|
|
41
|
+
try {
|
|
42
|
+
const validatedBasePadding = validateNumber(basePadding, 'basePadding', 0, 100);
|
|
43
|
+
validateSafeAreaInsets(insets);
|
|
44
|
+
|
|
45
|
+
const { left = 0, right = 0 } = insets;
|
|
46
|
+
const isTabletDevice = isTablet();
|
|
47
|
+
|
|
48
|
+
if (isTabletDevice) {
|
|
49
|
+
const tabletPadding = validatedBasePadding * LAYOUT_CONSTANTS.SPACING_MULTIPLIER_TABLET;
|
|
50
|
+
return Math.max(
|
|
51
|
+
tabletPadding,
|
|
52
|
+
left + LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE,
|
|
53
|
+
right + LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return Math.max(
|
|
58
|
+
validatedBasePadding,
|
|
59
|
+
left + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET,
|
|
60
|
+
right + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET
|
|
61
|
+
);
|
|
62
|
+
} catch {
|
|
63
|
+
return 16;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Positioning Utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isTablet } from '../../device/detection';
|
|
6
|
+
import { LAYOUT_CONSTANTS } from '../config';
|
|
7
|
+
import { validateNumber, validateSafeAreaInsets } from '../validation';
|
|
8
|
+
|
|
9
|
+
export const getResponsiveBottomPosition = (
|
|
10
|
+
basePosition: number = LAYOUT_CONSTANTS.BOTTOM_POSITION_BASE,
|
|
11
|
+
insets: { bottom?: number } = { bottom: 0 }
|
|
12
|
+
): number => {
|
|
13
|
+
try {
|
|
14
|
+
const validatedBasePosition = validateNumber(basePosition, 'basePosition', 0, 500);
|
|
15
|
+
validateSafeAreaInsets(insets);
|
|
16
|
+
|
|
17
|
+
const { bottom = 0 } = insets;
|
|
18
|
+
return Math.max(validatedBasePosition, bottom + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET);
|
|
19
|
+
} catch {
|
|
20
|
+
return 32;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const getResponsiveFABPosition = (
|
|
25
|
+
insets: { bottom?: number; right?: number } = { bottom: 0, right: 0 }
|
|
26
|
+
): { bottom: number; right: number } => {
|
|
27
|
+
try {
|
|
28
|
+
validateSafeAreaInsets(insets);
|
|
29
|
+
const { bottom = 0, right = 0 } = insets;
|
|
30
|
+
const isTabletDevice = isTablet();
|
|
31
|
+
|
|
32
|
+
if (isTabletDevice) {
|
|
33
|
+
return {
|
|
34
|
+
bottom: Math.max(
|
|
35
|
+
LAYOUT_CONSTANTS.FAB_BOTTOM_TABLET,
|
|
36
|
+
bottom + LAYOUT_CONSTANTS.TAB_BAR_OFFSET
|
|
37
|
+
),
|
|
38
|
+
right: Math.max(
|
|
39
|
+
LAYOUT_CONSTANTS.FAB_RIGHT_TABLET,
|
|
40
|
+
right + LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
bottom: Math.max(
|
|
47
|
+
LAYOUT_CONSTANTS.TAB_BAR_OFFSET,
|
|
48
|
+
bottom + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET
|
|
49
|
+
),
|
|
50
|
+
right: Math.max(
|
|
51
|
+
LAYOUT_CONSTANTS.FAB_RIGHT_PHONE,
|
|
52
|
+
right + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
} catch {
|
|
56
|
+
return {
|
|
57
|
+
bottom: LAYOUT_CONSTANTS.TAB_BAR_OFFSET,
|
|
58
|
+
right: LAYOUT_CONSTANTS.FAB_RIGHT_PHONE,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
};
|
|
@@ -1,270 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Responsive Layout Utilities
|
|
3
|
-
* Layout utilities for positioning and spacing.
|
|
2
|
+
* Responsive Layout Utilities - Barrel Export
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
// Screen layout
|
|
6
|
+
export { getScreenLayoutConfig } from './screen/screenLayoutConfig';
|
|
7
|
+
export type { ScreenLayoutConfig } from './screen/screenLayoutConfig';
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* Uses expo-device based detection for accuracy
|
|
13
|
-
*/
|
|
14
|
-
const checkIsTabletSize = (): boolean => isTablet();
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Screen layout configuration for ScreenLayout component
|
|
18
|
-
*/
|
|
19
|
-
export interface ScreenLayoutConfig {
|
|
20
|
-
maxContentWidth: number | undefined;
|
|
21
|
-
horizontalPadding: number;
|
|
22
|
-
verticalPadding: number;
|
|
23
|
-
spacingMultiplier: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Get complete screen layout configuration
|
|
28
|
-
* Returns all responsive values needed for ScreenLayout
|
|
29
|
-
*/
|
|
30
|
-
export const getScreenLayoutConfig = (
|
|
31
|
-
insets: { left?: number; right?: number; top?: number; bottom?: number } = {}
|
|
32
|
-
): ScreenLayoutConfig => {
|
|
33
|
-
try {
|
|
34
|
-
const isTabletDevice = checkIsTabletSize();
|
|
35
|
-
const spacingMultiplier = getSpacingMultiplier();
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
maxContentWidth: isTabletDevice ? SIZE_CONSTRAINTS.CONTENT_MAX_TABLET : undefined,
|
|
39
|
-
horizontalPadding: getResponsiveHorizontalPadding(LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE, insets),
|
|
40
|
-
verticalPadding: getResponsiveVerticalPadding(insets),
|
|
41
|
-
spacingMultiplier,
|
|
42
|
-
};
|
|
43
|
-
} catch {
|
|
44
|
-
return {
|
|
45
|
-
maxContentWidth: undefined,
|
|
46
|
-
horizontalPadding: LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE,
|
|
47
|
-
verticalPadding: LAYOUT_CONSTANTS.VERTICAL_PADDING_STANDARD,
|
|
48
|
-
spacingMultiplier: LAYOUT_CONSTANTS.SPACING_MULTIPLIER_STANDARD,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Responsive vertical padding
|
|
55
|
-
* Adjusts based on device type and safe area insets
|
|
56
|
-
*/
|
|
57
|
-
export const getResponsiveVerticalPadding = (
|
|
58
|
-
insets: { top?: number; bottom?: number } = { top: 0, bottom: 0 }
|
|
59
|
-
): number => {
|
|
60
|
-
try {
|
|
61
|
-
validateSafeAreaInsets(insets);
|
|
62
|
-
const { top = 0 } = insets;
|
|
63
|
-
const isTabletDevice = checkIsTabletSize();
|
|
64
|
-
const isSmall = isSmallPhone();
|
|
65
|
-
const spacingMultiplier = getSpacingMultiplier();
|
|
66
|
-
|
|
67
|
-
// Base padding adjusted by device type
|
|
68
|
-
let basePadding: number = LAYOUT_CONSTANTS.VERTICAL_PADDING_STANDARD;
|
|
69
|
-
if (isTabletDevice) {
|
|
70
|
-
basePadding = LAYOUT_CONSTANTS.VERTICAL_PADDING_TABLET;
|
|
71
|
-
} else if (isSmall) {
|
|
72
|
-
basePadding = LAYOUT_CONSTANTS.VERTICAL_PADDING_SMALL;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Apply spacing multiplier for consistency
|
|
76
|
-
const adjustedPadding = basePadding * spacingMultiplier;
|
|
77
|
-
|
|
78
|
-
// Ensure minimum padding respects safe area
|
|
79
|
-
return Math.max(adjustedPadding, top > 0 ? 8 : adjustedPadding);
|
|
80
|
-
} catch {
|
|
81
|
-
return LAYOUT_CONSTANTS.VERTICAL_PADDING_STANDARD;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Responsive horizontal padding
|
|
87
|
-
*/
|
|
88
|
-
export const getResponsiveHorizontalPadding = (
|
|
89
|
-
basePadding: number = LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE,
|
|
90
|
-
insets: { left?: number; right?: number } = { left: 0, right: 0 }
|
|
91
|
-
): number => {
|
|
92
|
-
try {
|
|
93
|
-
const validatedBasePadding = validateNumber(basePadding, 'basePadding', 0, 100);
|
|
94
|
-
validateSafeAreaInsets(insets);
|
|
95
|
-
|
|
96
|
-
const { left = 0, right = 0 } = insets;
|
|
97
|
-
const isTabletDevice = checkIsTabletSize();
|
|
98
|
-
|
|
99
|
-
if (isTabletDevice) {
|
|
100
|
-
const tabletPadding = validatedBasePadding * LAYOUT_CONSTANTS.SPACING_MULTIPLIER_TABLET;
|
|
101
|
-
return Math.max(
|
|
102
|
-
tabletPadding,
|
|
103
|
-
left + LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE,
|
|
104
|
-
right + LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return Math.max(
|
|
109
|
-
validatedBasePadding,
|
|
110
|
-
left + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET,
|
|
111
|
-
right + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET
|
|
112
|
-
);
|
|
113
|
-
} catch {
|
|
114
|
-
return 16;
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Responsive bottom positioning
|
|
120
|
-
*/
|
|
121
|
-
export const getResponsiveBottomPosition = (
|
|
122
|
-
basePosition: number = LAYOUT_CONSTANTS.BOTTOM_POSITION_BASE,
|
|
123
|
-
insets: { bottom?: number } = { bottom: 0 }
|
|
124
|
-
): number => {
|
|
125
|
-
try {
|
|
126
|
-
const validatedBasePosition = validateNumber(basePosition, 'basePosition', 0, 500);
|
|
127
|
-
validateSafeAreaInsets(insets);
|
|
128
|
-
|
|
129
|
-
const { bottom = 0 } = insets;
|
|
130
|
-
return Math.max(validatedBasePosition, bottom + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET);
|
|
131
|
-
} catch {
|
|
132
|
-
return 32;
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Responsive FAB position
|
|
138
|
-
*/
|
|
139
|
-
export const getResponsiveFABPosition = (
|
|
140
|
-
insets: { bottom?: number; right?: number } = { bottom: 0, right: 0 }
|
|
141
|
-
): { bottom: number; right: number } => {
|
|
142
|
-
try {
|
|
143
|
-
validateSafeAreaInsets(insets);
|
|
144
|
-
const { bottom = 0, right = 0 } = insets;
|
|
145
|
-
const isTabletDevice = checkIsTabletSize();
|
|
146
|
-
|
|
147
|
-
if (isTabletDevice) {
|
|
148
|
-
return {
|
|
149
|
-
bottom: Math.max(
|
|
150
|
-
LAYOUT_CONSTANTS.FAB_BOTTOM_TABLET,
|
|
151
|
-
bottom + LAYOUT_CONSTANTS.TAB_BAR_OFFSET
|
|
152
|
-
),
|
|
153
|
-
right: Math.max(
|
|
154
|
-
LAYOUT_CONSTANTS.FAB_RIGHT_TABLET,
|
|
155
|
-
right + LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE
|
|
156
|
-
),
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
bottom: Math.max(
|
|
162
|
-
LAYOUT_CONSTANTS.TAB_BAR_OFFSET,
|
|
163
|
-
bottom + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET
|
|
164
|
-
),
|
|
165
|
-
right: Math.max(
|
|
166
|
-
LAYOUT_CONSTANTS.FAB_RIGHT_PHONE,
|
|
167
|
-
right + LAYOUT_CONSTANTS.SAFE_AREA_OFFSET
|
|
168
|
-
),
|
|
169
|
-
};
|
|
170
|
-
} catch {
|
|
171
|
-
return {
|
|
172
|
-
bottom: LAYOUT_CONSTANTS.TAB_BAR_OFFSET,
|
|
173
|
-
right: LAYOUT_CONSTANTS.FAB_RIGHT_PHONE,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Tab bar height constants
|
|
180
|
-
*/
|
|
181
|
-
const TAB_BAR_CONSTANTS = {
|
|
182
|
-
BASE_HEIGHT_PHONE: 60,
|
|
183
|
-
BASE_HEIGHT_TABLET: 70,
|
|
184
|
-
MIN_PADDING_BOTTOM: 8,
|
|
185
|
-
MIN_PADDING_TOP: 8,
|
|
186
|
-
ICON_SIZE_PHONE: 24,
|
|
187
|
-
ICON_SIZE_TABLET: 28,
|
|
188
|
-
FAB_SIZE_PHONE: 64,
|
|
189
|
-
FAB_SIZE_TABLET: 72,
|
|
190
|
-
FAB_OFFSET_Y_PHONE: -24,
|
|
191
|
-
FAB_OFFSET_Y_TABLET: -28,
|
|
192
|
-
} as const;
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Responsive tab bar configuration
|
|
196
|
-
*/
|
|
197
|
-
export interface ResponsiveTabBarConfig {
|
|
198
|
-
height: number;
|
|
199
|
-
paddingBottom: number;
|
|
200
|
-
paddingTop: number;
|
|
201
|
-
iconSize: number;
|
|
202
|
-
fabSize: number;
|
|
203
|
-
fabOffsetY: number;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Get responsive tab bar height based on device and safe area
|
|
208
|
-
*/
|
|
209
|
-
export const getResponsiveTabBarHeight = (
|
|
210
|
-
insets: { bottom?: number } = { bottom: 0 }
|
|
211
|
-
): number => {
|
|
212
|
-
try {
|
|
213
|
-
validateSafeAreaInsets(insets);
|
|
214
|
-
const { bottom = 0 } = insets;
|
|
215
|
-
const isTabletDevice = checkIsTabletSize();
|
|
216
|
-
|
|
217
|
-
const baseHeight = isTabletDevice
|
|
218
|
-
? TAB_BAR_CONSTANTS.BASE_HEIGHT_TABLET
|
|
219
|
-
: TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE;
|
|
220
|
-
|
|
221
|
-
const bottomPadding = Math.max(bottom, TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM);
|
|
222
|
-
|
|
223
|
-
return baseHeight + bottomPadding;
|
|
224
|
-
} catch {
|
|
225
|
-
return TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE + TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM;
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Get complete responsive tab bar configuration
|
|
231
|
-
*/
|
|
232
|
-
export const getResponsiveTabBarConfig = (
|
|
233
|
-
insets: { bottom?: number } = { bottom: 0 }
|
|
234
|
-
): ResponsiveTabBarConfig => {
|
|
235
|
-
try {
|
|
236
|
-
validateSafeAreaInsets(insets);
|
|
237
|
-
const { bottom = 0 } = insets;
|
|
238
|
-
const isTabletSize = checkIsTabletSize();
|
|
239
|
-
|
|
240
|
-
const baseHeight = isTabletSize
|
|
241
|
-
? TAB_BAR_CONSTANTS.BASE_HEIGHT_TABLET
|
|
242
|
-
: TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE;
|
|
9
|
+
// Padding utilities
|
|
10
|
+
export { getResponsiveVerticalPadding, getResponsiveHorizontalPadding } from './padding/paddingUtils';
|
|
243
11
|
|
|
244
|
-
|
|
12
|
+
// Positioning utilities
|
|
13
|
+
export { getResponsiveBottomPosition, getResponsiveFABPosition } from './positioning/positioningUtils';
|
|
245
14
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
paddingTop: TAB_BAR_CONSTANTS.MIN_PADDING_TOP,
|
|
250
|
-
iconSize: isTabletSize
|
|
251
|
-
? TAB_BAR_CONSTANTS.ICON_SIZE_TABLET
|
|
252
|
-
: TAB_BAR_CONSTANTS.ICON_SIZE_PHONE,
|
|
253
|
-
fabSize: isTabletSize
|
|
254
|
-
? TAB_BAR_CONSTANTS.FAB_SIZE_TABLET
|
|
255
|
-
: TAB_BAR_CONSTANTS.FAB_SIZE_PHONE,
|
|
256
|
-
fabOffsetY: isTabletSize
|
|
257
|
-
? TAB_BAR_CONSTANTS.FAB_OFFSET_Y_TABLET
|
|
258
|
-
: TAB_BAR_CONSTANTS.FAB_OFFSET_Y_PHONE,
|
|
259
|
-
};
|
|
260
|
-
} catch {
|
|
261
|
-
return {
|
|
262
|
-
height: TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE + TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM,
|
|
263
|
-
paddingBottom: TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM,
|
|
264
|
-
paddingTop: TAB_BAR_CONSTANTS.MIN_PADDING_TOP,
|
|
265
|
-
iconSize: TAB_BAR_CONSTANTS.ICON_SIZE_PHONE,
|
|
266
|
-
fabSize: TAB_BAR_CONSTANTS.FAB_SIZE_PHONE,
|
|
267
|
-
fabOffsetY: TAB_BAR_CONSTANTS.FAB_OFFSET_Y_PHONE,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
};
|
|
15
|
+
// Tab bar configuration
|
|
16
|
+
export { getResponsiveTabBarHeight, getResponsiveTabBarConfig } from './tabbar/tabBarConfig';
|
|
17
|
+
export type { ResponsiveTabBarConfig } from './tabbar/tabBarConfig';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screen Layout Configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isTablet, getSpacingMultiplier } from '../../device/detection';
|
|
6
|
+
import { LAYOUT_CONSTANTS, SIZE_CONSTRAINTS } from '../config';
|
|
7
|
+
import { getResponsiveHorizontalPadding } from '../padding/paddingUtils';
|
|
8
|
+
import { getResponsiveVerticalPadding } from '../padding/paddingUtils';
|
|
9
|
+
|
|
10
|
+
export interface ScreenLayoutConfig {
|
|
11
|
+
readonly maxContentWidth: number | undefined;
|
|
12
|
+
readonly horizontalPadding: number;
|
|
13
|
+
readonly verticalPadding: number;
|
|
14
|
+
readonly spacingMultiplier: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const getScreenLayoutConfig = (
|
|
18
|
+
insets: { left?: number; right?: number; top?: number; bottom?: number } = {}
|
|
19
|
+
): ScreenLayoutConfig => {
|
|
20
|
+
try {
|
|
21
|
+
const isTabletDevice = isTablet();
|
|
22
|
+
const spacingMultiplier = getSpacingMultiplier();
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
maxContentWidth: isTabletDevice ? SIZE_CONSTRAINTS.CONTENT_MAX_TABLET : undefined,
|
|
26
|
+
horizontalPadding: getResponsiveHorizontalPadding(LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE, insets),
|
|
27
|
+
verticalPadding: getResponsiveVerticalPadding(insets),
|
|
28
|
+
spacingMultiplier,
|
|
29
|
+
};
|
|
30
|
+
} catch {
|
|
31
|
+
return {
|
|
32
|
+
maxContentWidth: undefined,
|
|
33
|
+
horizontalPadding: LAYOUT_CONSTANTS.HORIZONTAL_PADDING_BASE,
|
|
34
|
+
verticalPadding: LAYOUT_CONSTANTS.VERTICAL_PADDING_STANDARD,
|
|
35
|
+
spacingMultiplier: LAYOUT_CONSTANTS.SPACING_MULTIPLIER_STANDARD,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tab Bar Configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isTablet } from '../../device/detection';
|
|
6
|
+
import { validateSafeAreaInsets } from '../validation';
|
|
7
|
+
|
|
8
|
+
const TAB_BAR_CONSTANTS = {
|
|
9
|
+
BASE_HEIGHT_PHONE: 60,
|
|
10
|
+
BASE_HEIGHT_TABLET: 70,
|
|
11
|
+
MIN_PADDING_BOTTOM: 8,
|
|
12
|
+
MIN_PADDING_TOP: 8,
|
|
13
|
+
ICON_SIZE_PHONE: 24,
|
|
14
|
+
ICON_SIZE_TABLET: 28,
|
|
15
|
+
FAB_SIZE_PHONE: 64,
|
|
16
|
+
FAB_SIZE_TABLET: 72,
|
|
17
|
+
FAB_OFFSET_Y_PHONE: -24,
|
|
18
|
+
FAB_OFFSET_Y_TABLET: -28,
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export interface ResponsiveTabBarConfig {
|
|
22
|
+
readonly height: number;
|
|
23
|
+
readonly paddingBottom: number;
|
|
24
|
+
readonly paddingTop: number;
|
|
25
|
+
readonly iconSize: number;
|
|
26
|
+
readonly fabSize: number;
|
|
27
|
+
readonly fabOffsetY: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const getResponsiveTabBarHeight = (
|
|
31
|
+
insets: { bottom?: number } = { bottom: 0 }
|
|
32
|
+
): number => {
|
|
33
|
+
try {
|
|
34
|
+
validateSafeAreaInsets(insets);
|
|
35
|
+
const { bottom = 0 } = insets;
|
|
36
|
+
const isTabletDevice = isTablet();
|
|
37
|
+
|
|
38
|
+
const baseHeight = isTabletDevice
|
|
39
|
+
? TAB_BAR_CONSTANTS.BASE_HEIGHT_TABLET
|
|
40
|
+
: TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE;
|
|
41
|
+
|
|
42
|
+
const bottomPadding = Math.max(bottom, TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM);
|
|
43
|
+
|
|
44
|
+
return baseHeight + bottomPadding;
|
|
45
|
+
} catch {
|
|
46
|
+
return TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE + TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const getResponsiveTabBarConfig = (
|
|
51
|
+
insets: { bottom?: number } = { bottom: 0 }
|
|
52
|
+
): ResponsiveTabBarConfig => {
|
|
53
|
+
try {
|
|
54
|
+
validateSafeAreaInsets(insets);
|
|
55
|
+
const { bottom = 0 } = insets;
|
|
56
|
+
const isTabletSize = isTablet();
|
|
57
|
+
|
|
58
|
+
const baseHeight = isTabletSize
|
|
59
|
+
? TAB_BAR_CONSTANTS.BASE_HEIGHT_TABLET
|
|
60
|
+
: TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE;
|
|
61
|
+
|
|
62
|
+
const paddingBottom = Math.max(bottom, TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
height: baseHeight + paddingBottom,
|
|
66
|
+
paddingBottom,
|
|
67
|
+
paddingTop: TAB_BAR_CONSTANTS.MIN_PADDING_TOP,
|
|
68
|
+
iconSize: isTabletSize
|
|
69
|
+
? TAB_BAR_CONSTANTS.ICON_SIZE_TABLET
|
|
70
|
+
: TAB_BAR_CONSTANTS.ICON_SIZE_PHONE,
|
|
71
|
+
fabSize: isTabletSize
|
|
72
|
+
? TAB_BAR_CONSTANTS.FAB_SIZE_TABLET
|
|
73
|
+
: TAB_BAR_CONSTANTS.FAB_SIZE_PHONE,
|
|
74
|
+
fabOffsetY: isTabletSize
|
|
75
|
+
? TAB_BAR_CONSTANTS.FAB_OFFSET_Y_TABLET
|
|
76
|
+
: TAB_BAR_CONSTANTS.FAB_OFFSET_Y_PHONE,
|
|
77
|
+
};
|
|
78
|
+
} catch {
|
|
79
|
+
return {
|
|
80
|
+
height: TAB_BAR_CONSTANTS.BASE_HEIGHT_PHONE + TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM,
|
|
81
|
+
paddingBottom: TAB_BAR_CONSTANTS.MIN_PADDING_BOTTOM,
|
|
82
|
+
paddingTop: TAB_BAR_CONSTANTS.MIN_PADDING_TOP,
|
|
83
|
+
iconSize: TAB_BAR_CONSTANTS.ICON_SIZE_PHONE,
|
|
84
|
+
fabSize: TAB_BAR_CONSTANTS.FAB_SIZE_PHONE,
|
|
85
|
+
fabOffsetY: TAB_BAR_CONSTANTS.FAB_OFFSET_Y_PHONE,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Responsive Hook Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { DeviceType } from '../../device/detection';
|
|
6
|
+
import type { ResponsiveModalLayout, ResponsiveBottomSheetLayout, ResponsiveDialogLayout } from '../responsive';
|
|
7
|
+
import type { ResponsiveTabBarConfig, ScreenLayoutConfig } from '../responsiveLayout';
|
|
8
|
+
|
|
9
|
+
export interface UseResponsiveReturn {
|
|
10
|
+
// Device info
|
|
11
|
+
readonly width: number;
|
|
12
|
+
readonly height: number;
|
|
13
|
+
readonly isSmallDevice: boolean;
|
|
14
|
+
readonly isTabletDevice: boolean;
|
|
15
|
+
readonly isLandscapeDevice: boolean;
|
|
16
|
+
readonly deviceType: DeviceType;
|
|
17
|
+
|
|
18
|
+
// Safe area insets
|
|
19
|
+
readonly insets: {
|
|
20
|
+
readonly top: number;
|
|
21
|
+
readonly bottom: number;
|
|
22
|
+
readonly left: number;
|
|
23
|
+
readonly right: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Responsive sizes
|
|
27
|
+
readonly logoSize: number;
|
|
28
|
+
readonly inputHeight: number;
|
|
29
|
+
readonly iconContainerSize: number;
|
|
30
|
+
readonly maxContentWidth: number;
|
|
31
|
+
readonly minTouchTarget: number;
|
|
32
|
+
|
|
33
|
+
// Responsive positioning
|
|
34
|
+
readonly horizontalPadding: number;
|
|
35
|
+
readonly verticalPadding: number;
|
|
36
|
+
readonly bottomPosition: number;
|
|
37
|
+
readonly fabPosition: { readonly bottom: number; readonly right: number };
|
|
38
|
+
|
|
39
|
+
// Screen layout config
|
|
40
|
+
readonly screenLayoutConfig: ScreenLayoutConfig;
|
|
41
|
+
|
|
42
|
+
// Responsive layout
|
|
43
|
+
readonly modalMaxHeight: string;
|
|
44
|
+
readonly modalMinHeight: number;
|
|
45
|
+
readonly gridColumns: number;
|
|
46
|
+
readonly spacingMultiplier: number;
|
|
47
|
+
readonly tabBarConfig: ResponsiveTabBarConfig;
|
|
48
|
+
|
|
49
|
+
// Modal layouts
|
|
50
|
+
readonly modalLayout: ResponsiveModalLayout;
|
|
51
|
+
readonly bottomSheetLayout: ResponsiveBottomSheetLayout;
|
|
52
|
+
readonly dialogLayout: ResponsiveDialogLayout;
|
|
53
|
+
|
|
54
|
+
// Onboarding specific
|
|
55
|
+
readonly onboardingIconSize: number;
|
|
56
|
+
readonly onboardingIconMarginTop: number;
|
|
57
|
+
readonly onboardingIconMarginBottom: number;
|
|
58
|
+
readonly onboardingTitleMarginBottom: number;
|
|
59
|
+
readonly onboardingDescriptionMarginTop: number;
|
|
60
|
+
readonly onboardingTextPadding: number;
|
|
61
|
+
|
|
62
|
+
// Utility functions
|
|
63
|
+
readonly getLogoSize: (baseSize?: number) => number;
|
|
64
|
+
readonly getInputHeight: (baseHeight?: number) => number;
|
|
65
|
+
readonly getIconSize: (baseSize?: number) => number;
|
|
66
|
+
readonly getMaxWidth: (baseWidth?: number) => number;
|
|
67
|
+
readonly getFontSize: (baseFontSize: number) => number;
|
|
68
|
+
readonly getGridCols: (mobile?: number, tablet?: number) => number;
|
|
69
|
+
}
|