@umituz/react-native-design-system 2.6.64 → 2.6.66

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.6.64",
3
+ "version": "2.6.66",
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",
@@ -37,7 +37,7 @@
37
37
  * @module AtomicDatePicker
38
38
  */
39
39
 
40
- import React, { useState, useMemo } from 'react';
40
+ import React, { useState } from 'react';
41
41
  import {
42
42
  View,
43
43
  StyleSheet,
@@ -50,6 +50,8 @@ import { useAppDesignTokens } from '../theme';
50
50
  import { AtomicText } from './AtomicText';
51
51
  import { DatePickerModal } from './datepicker/components/DatePickerModal';
52
52
  import { DatePickerButton } from './datepicker/components/DatePickerButton';
53
+ import { useDatePickerText } from './datepicker/hooks/useDatePickerText';
54
+ import { getDatePickerStyles } from './datepicker/styles/datePickerStyles';
53
55
 
54
56
  /**
55
57
  * Props for AtomicDatePicker component
@@ -139,45 +141,8 @@ export const AtomicDatePicker: React.FC<AtomicDatePickerProps> = ({
139
141
  }
140
142
  };
141
143
 
142
- /**
143
- * Format date based on mode
144
- * Uses native Date formatting (locale-aware)
145
- */
146
- const formatDate = useMemo(() => (date: Date): string => {
147
- if (mode === 'time') {
148
- return date.toLocaleTimeString([], {
149
- hour: '2-digit',
150
- minute: '2-digit'
151
- });
152
- }
153
- if (mode === 'datetime') {
154
- const dateStr = date.toLocaleDateString([], {
155
- year: 'numeric',
156
- month: 'short',
157
- day: 'numeric',
158
- });
159
- const timeStr = date.toLocaleTimeString([], {
160
- hour: '2-digit',
161
- minute: '2-digit'
162
- });
163
- return `${dateStr} ${timeStr}`;
164
- }
165
- return date.toLocaleDateString([], {
166
- year: 'numeric',
167
- month: 'long',
168
- day: 'numeric',
169
- });
170
- }, [mode]);
171
-
172
- /**
173
- * Get display text for the button
174
- */
175
- const displayText = useMemo(() => {
176
- if (!value) return placeholder;
177
- return formatDate(value);
178
- }, [value, placeholder, formatDate]);
179
-
180
- const styles = getStyles(tokens);
144
+ const { displayText } = useDatePickerText({ value, placeholder, mode });
145
+ const styles = getDatePickerStyles(tokens);
181
146
 
182
147
  return (
183
148
  <View style={[styles.container, style]} testID={testID}>
@@ -229,26 +194,3 @@ export const AtomicDatePicker: React.FC<AtomicDatePickerProps> = ({
229
194
  </View>
230
195
  );
231
196
  };
232
-
233
- /**
234
- * Get component styles based on design tokens
235
- */
236
- const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) => {
237
- return StyleSheet.create({
238
- container: {
239
- marginBottom: tokens.spacing.md,
240
- },
241
- label: {
242
- fontSize: tokens.typography.bodyMedium.responsiveFontSize,
243
- fontWeight: tokens.typography.semibold,
244
- color: tokens.colors.onSurface,
245
- marginBottom: tokens.spacing.sm,
246
- },
247
- errorText: {
248
- fontSize: tokens.typography.bodySmall.responsiveFontSize,
249
- color: tokens.colors.error,
250
- marginTop: tokens.spacing.xs,
251
- marginLeft: tokens.spacing.xs,
252
- },
253
- });
254
- };
@@ -3,6 +3,7 @@ import { View, TextInput, StyleSheet, StyleProp, ViewStyle, TextStyle } from 're
3
3
  import { useAppDesignTokens } from '../theme';
4
4
  import { useInputState } from './input/hooks/useInputState';
5
5
  import { getSizeConfig, getVariantStyle, getTextColor } from './input/styles/inputStylesHelper';
6
+ import { inputStyles } from './input/styles/inputStyles';
6
7
  import type { AtomicInputProps } from './input/types';
7
8
  import { InputLabel } from './input/components/InputLabel';
8
9
  import { InputIcon } from './input/components/InputIcon';
@@ -94,7 +95,7 @@ export const AtomicInput = React.forwardRef<TextInput, AtomicInputProps>(({
94
95
  const iconColor = isDisabled ? tokens.colors.textDisabled : tokens.colors.textSecondary;
95
96
 
96
97
  const containerStyle: StyleProp<ViewStyle> = [
97
- styles.container,
98
+ inputStyles.container,
98
99
  variantStyle,
99
100
  {
100
101
  paddingTop: sizeConfig.paddingVertical,
@@ -108,7 +109,7 @@ export const AtomicInput = React.forwardRef<TextInput, AtomicInputProps>(({
108
109
  ];
109
110
 
110
111
  const textInputStyle: StyleProp<TextStyle> = [
111
- styles.input,
112
+ inputStyles.input,
112
113
  {
113
114
  fontSize: sizeConfig.fontSize,
114
115
  lineHeight: (sizeConfig.fontSize || 16) * 1.2,
@@ -198,15 +199,3 @@ export const AtomicInput = React.forwardRef<TextInput, AtomicInputProps>(({
198
199
  </View>
199
200
  );
200
201
  });
201
-
202
- const styles = StyleSheet.create({
203
- container: {
204
- flexDirection: 'row',
205
- alignItems: 'center',
206
- },
207
- input: {
208
- flex: 1,
209
- margin: 0,
210
- padding: 0,
211
- },
212
- });
@@ -52,6 +52,7 @@ import { AtomicIcon } from './AtomicIcon';
52
52
  import { AtomicText } from './AtomicText';
53
53
  import { PickerModal } from './picker/components/PickerModal';
54
54
  import { PickerChips } from './picker/components/PickerChips';
55
+ import { PickerIcons } from './picker/components/PickerIcons';
55
56
  import {
56
57
  getPickerContainerStyles,
57
58
  getPickerLabelStyles,
@@ -156,27 +157,15 @@ export const AtomicPicker: React.FC<AtomicPickerProps> = ({
156
157
  </AtomicText>
157
158
 
158
159
  {/* Icons */}
159
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: tokens.spacing.xs }}>
160
- {/* Clear Button */}
161
- {clearable && pickerState.selectedOptions.length > 0 && !disabled && (
162
- <TouchableOpacity
163
- onPress={pickerState.handleClear}
164
- hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
165
- accessibilityRole="button"
166
- accessibilityLabel={clearAccessibilityLabel}
167
- testID={`${testID}-clear`}
168
- >
169
- <AtomicIcon name="X" size="sm" color="secondary" />
170
- </TouchableOpacity>
171
- )}
172
-
173
- {/* Dropdown Icon */}
174
- <AtomicIcon
175
- name={pickerState.modalVisible ? 'ChevronUp' : 'ChevronDown'}
176
- size="sm"
177
- color={disabled ? 'surfaceVariant' : 'secondary'}
178
- />
179
- </View>
160
+ <PickerIcons
161
+ clearable={clearable}
162
+ disabled={disabled}
163
+ modalVisible={pickerState.modalVisible}
164
+ selectedOptionsCount={pickerState.selectedOptions.length}
165
+ onClear={pickerState.handleClear}
166
+ clearAccessibilityLabel={clearAccessibilityLabel}
167
+ testID={testID}
168
+ />
180
169
  </TouchableOpacity>
181
170
 
182
171
  {/* Selected Chips (Multi-select) */}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * useDatePickerText Hook
3
+ * Handles date formatting and display text for date picker
4
+ */
5
+
6
+ import { useMemo } from 'react';
7
+ import type { DatepickerMode } from '../types';
8
+
9
+ interface UseDatePickerTextProps {
10
+ value: Date | null;
11
+ placeholder: string;
12
+ mode: DatepickerMode;
13
+ }
14
+
15
+ interface UseDatePickerTextResult {
16
+ displayText: string;
17
+ formatDate: (date: Date) => string;
18
+ }
19
+
20
+ export const useDatePickerText = ({
21
+ value,
22
+ placeholder,
23
+ mode,
24
+ }: UseDatePickerTextProps): UseDatePickerTextResult => {
25
+ /**
26
+ * Format date based on mode
27
+ * Uses native Date formatting (locale-aware)
28
+ */
29
+ const formatDate = useMemo(() => (date: Date): string => {
30
+ if (mode === 'time') {
31
+ return date.toLocaleTimeString([], {
32
+ hour: '2-digit',
33
+ minute: '2-digit'
34
+ });
35
+ }
36
+ if (mode === 'datetime') {
37
+ const dateStr = date.toLocaleDateString([], {
38
+ year: 'numeric',
39
+ month: 'short',
40
+ day: 'numeric',
41
+ });
42
+ const timeStr = date.toLocaleTimeString([], {
43
+ hour: '2-digit',
44
+ minute: '2-digit'
45
+ });
46
+ return `${dateStr} ${timeStr}`;
47
+ }
48
+ return date.toLocaleDateString([], {
49
+ year: 'numeric',
50
+ month: 'long',
51
+ day: 'numeric',
52
+ });
53
+ }, [mode]);
54
+
55
+ /**
56
+ * Get display text for the button
57
+ */
58
+ const displayText = useMemo(() => {
59
+ if (!value) return placeholder;
60
+ return formatDate(value);
61
+ }, [value, placeholder, formatDate]);
62
+
63
+ return { displayText, formatDate };
64
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * DatePicker Styles
3
+ * StyleSheet generator for AtomicDatePicker component
4
+ */
5
+
6
+ import { StyleSheet } from 'react-native';
7
+ import type { DesignTokens } from '../../theme';
8
+
9
+ export const getDatePickerStyles = (tokens: DesignTokens) => {
10
+ return StyleSheet.create({
11
+ container: {
12
+ marginBottom: tokens.spacing.md,
13
+ },
14
+ label: {
15
+ fontSize: tokens.typography.bodyMedium.responsiveFontSize,
16
+ fontWeight: tokens.typography.semibold,
17
+ color: tokens.colors.onSurface,
18
+ marginBottom: tokens.spacing.sm,
19
+ },
20
+ errorText: {
21
+ fontSize: tokens.typography.bodySmall.responsiveFontSize,
22
+ color: tokens.colors.error,
23
+ marginTop: tokens.spacing.xs,
24
+ marginLeft: tokens.spacing.xs,
25
+ },
26
+ });
27
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * AtomicInput Styles
3
+ * StyleSheet for AtomicInput component
4
+ */
5
+
6
+ import { StyleSheet } from 'react-native';
7
+
8
+ export const inputStyles = StyleSheet.create({
9
+ container: {
10
+ flexDirection: 'row',
11
+ alignItems: 'center',
12
+ },
13
+ input: {
14
+ flex: 1,
15
+ margin: 0,
16
+ padding: 0,
17
+ },
18
+ });
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Picker Icons Component
3
+ * Renders clear button and dropdown icon for AtomicPicker
4
+ */
5
+
6
+ import React from 'react';
7
+ import { TouchableOpacity, View } from 'react-native';
8
+ import { useAppDesignTokens } from '../../theme';
9
+ import { AtomicIcon } from '../AtomicIcon';
10
+ import type { PickerOption } from '../picker/types';
11
+
12
+ interface PickerIconsProps {
13
+ clearable: boolean;
14
+ disabled: boolean;
15
+ modalVisible: boolean;
16
+ selectedOptionsCount: number;
17
+ onClear: () => void;
18
+ clearAccessibilityLabel?: string;
19
+ testID?: string;
20
+ }
21
+
22
+ export const PickerIcons: React.FC<PickerIconsProps> = ({
23
+ clearable,
24
+ disabled,
25
+ modalVisible,
26
+ selectedOptionsCount,
27
+ onClear,
28
+ clearAccessibilityLabel,
29
+ testID,
30
+ }) => {
31
+ const tokens = useAppDesignTokens();
32
+
33
+ return (
34
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: tokens.spacing.xs }}>
35
+ {/* Clear Button */}
36
+ {clearable && selectedOptionsCount > 0 && !disabled && (
37
+ <TouchableOpacity
38
+ onPress={onClear}
39
+ hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
40
+ accessibilityRole="button"
41
+ accessibilityLabel={clearAccessibilityLabel}
42
+ testID={`${testID}-clear`}
43
+ >
44
+ <AtomicIcon name="X" size="sm" color="secondary" />
45
+ </TouchableOpacity>
46
+ )}
47
+
48
+ {/* Dropdown Icon */}
49
+ <AtomicIcon
50
+ name={modalVisible ? 'ChevronUp' : 'ChevronDown'}
51
+ size="sm"
52
+ color={disabled ? 'surfaceVariant' : 'secondary'}
53
+ />
54
+ </View>
55
+ );
56
+ };
@@ -7,8 +7,7 @@ import { useMemo } from 'react';
7
7
  import { useCalendarEvents } from '../stores/useCalendarEvents';
8
8
  import { useCalendarNavigation } from '../stores/useCalendarNavigation';
9
9
  import { useCalendarView } from '../stores/useCalendarView';
10
- import { CalendarService } from '../../../services/CalendarService';
11
- import type { CalendarDay } from '../../../domain/entities/CalendarDay.entity';
10
+ import { CalendarService } from '../services/CalendarService';
12
11
 
13
12
  // Export individual stores
14
13
  export { useCalendarEvents } from '../stores/useCalendarEvents';
@@ -8,8 +8,8 @@ import { storageRepository } from '@umituz/react-native-storage';
8
8
  export const zustandStorage = {
9
9
  getItem: async (name: string): Promise<string | null> => {
10
10
  try {
11
- const result = await storageRepository.getItem<string>(name);
12
- if (result.success && result.data) {
11
+ const result = await storageRepository.getItem<string>(name, '');
12
+ if (result.success && result.data !== undefined) {
13
13
  return result.data;
14
14
  }
15
15
  return null;