@umituz/react-native-design-system 1.5.30 → 1.5.31
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": "1.5.
|
|
3
|
+
"version": "1.5.31",
|
|
4
4
|
"description": "Universal design system for React Native apps - Domain-Driven Design architecture with Material Design 3 components",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -37,13 +37,16 @@
|
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@expo/vector-icons": ">=14.0.0",
|
|
40
|
+
"@gorhom/bottom-sheet": ">=5.0.0",
|
|
40
41
|
"@react-native-community/datetimepicker": "^8.5.0",
|
|
41
42
|
"@react-navigation/native": "^6.0.0",
|
|
43
|
+
"@umituz/react-native-bottom-sheet": "*",
|
|
42
44
|
"@umituz/react-native-icon": "*",
|
|
43
45
|
"expo-linear-gradient": "^15.0.7",
|
|
44
46
|
"lucide-react-native": ">=0.468.0",
|
|
45
47
|
"react": ">=18.2.0 || ^19.0.0",
|
|
46
48
|
"react-native": ">=0.74.0",
|
|
49
|
+
"react-native-gesture-handler": ">=2.16.0",
|
|
47
50
|
"react-native-reanimated": "~3.10.1",
|
|
48
51
|
"react-native-svg": ">=13.0.0",
|
|
49
52
|
"zustand": "^5.0.2"
|
|
@@ -93,6 +96,7 @@
|
|
|
93
96
|
],
|
|
94
97
|
"dependencies": {
|
|
95
98
|
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
96
|
-
"@umituz/react-native-theme": "^1.2.5"
|
|
99
|
+
"@umituz/react-native-theme": "^1.2.5",
|
|
100
|
+
"@umituz/react-native-typography": "^1.1.0"
|
|
97
101
|
}
|
|
98
102
|
}
|
package/src/index.ts
CHANGED
|
@@ -34,6 +34,12 @@ export {
|
|
|
34
34
|
type AtomicTextProps,
|
|
35
35
|
} from './presentation/atoms/AtomicText';
|
|
36
36
|
|
|
37
|
+
// Re-export typography types for convenience (from @umituz/react-native-typography)
|
|
38
|
+
export type {
|
|
39
|
+
TextStyleVariant,
|
|
40
|
+
ColorVariant,
|
|
41
|
+
} from '@umituz/react-native-typography';
|
|
42
|
+
|
|
37
43
|
export {
|
|
38
44
|
AtomicCard,
|
|
39
45
|
type AtomicCardProps,
|
|
@@ -30,26 +30,27 @@
|
|
|
30
30
|
* ```
|
|
31
31
|
*
|
|
32
32
|
* Platform Behavior:
|
|
33
|
-
* -
|
|
34
|
-
* -
|
|
33
|
+
* - Opens bottom sheet from bottom with spinner wheel
|
|
34
|
+
* - Requires "Done" button to confirm selection
|
|
35
|
+
* - Can be dismissed by swiping down or tapping backdrop
|
|
35
36
|
*
|
|
36
37
|
* @module AtomicDatePicker
|
|
37
38
|
*/
|
|
38
39
|
|
|
39
|
-
import React, { useState } from 'react';
|
|
40
|
+
import React, { useState, useEffect } from 'react';
|
|
40
41
|
import {
|
|
41
42
|
View,
|
|
42
43
|
Text,
|
|
43
44
|
TouchableOpacity,
|
|
44
45
|
StyleSheet,
|
|
45
|
-
Modal,
|
|
46
46
|
useWindowDimensions,
|
|
47
47
|
} from 'react-native';
|
|
48
48
|
import DateTimePicker, { DateTimePickerEvent } from '@react-native-community/datetimepicker';
|
|
49
49
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
50
50
|
import { useAppDesignTokens } from '@umituz/react-native-theme';
|
|
51
|
-
import { useResponsive } from '../hooks/useResponsive';
|
|
52
51
|
import { AtomicIcon, type AtomicIconColor } from './AtomicIcon';
|
|
52
|
+
import { BottomSheet, useBottomSheet } from '@umituz/react-native-bottom-sheet';
|
|
53
|
+
import { AtomicButton } from './AtomicButton';
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
56
|
* Props for AtomicDatePicker component
|
|
@@ -102,28 +103,42 @@ export const AtomicDatePicker: React.FC<AtomicDatePickerProps> = ({
|
|
|
102
103
|
const tokens = useAppDesignTokens();
|
|
103
104
|
const { height } = useWindowDimensions();
|
|
104
105
|
const insets = useSafeAreaInsets();
|
|
105
|
-
const {
|
|
106
|
-
const [
|
|
106
|
+
const { sheetRef, open, close } = useBottomSheet();
|
|
107
|
+
const [tempDate, setTempDate] = useState<Date>(value || new Date());
|
|
108
|
+
|
|
109
|
+
// Update tempDate when value prop changes
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (value) {
|
|
112
|
+
setTempDate(value);
|
|
113
|
+
}
|
|
114
|
+
}, [value]);
|
|
107
115
|
|
|
108
116
|
/**
|
|
109
|
-
* Handle date/time change
|
|
110
|
-
*
|
|
111
|
-
* Note: event.type can be 'set', 'dismissed', or 'neutralButtonPressed'
|
|
117
|
+
* Handle date/time change in picker
|
|
118
|
+
* Updates temporary date state (not final until Done is pressed)
|
|
112
119
|
*/
|
|
113
120
|
const handleChange = (event: DateTimePickerEvent, selectedDate?: Date) => {
|
|
114
|
-
// Close picker when user confirms or dismisses
|
|
115
|
-
// iOS: Stays open until "Done" button (handled separately)
|
|
116
|
-
// Android/Web: Auto-closes on selection
|
|
117
|
-
if (event.type === 'set' || event.type === 'dismissed') {
|
|
118
|
-
setShow(false);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Update value only if date was selected (not dismissed)
|
|
122
121
|
if (event.type === 'set' && selectedDate) {
|
|
123
|
-
|
|
122
|
+
setTempDate(selectedDate);
|
|
124
123
|
}
|
|
125
124
|
};
|
|
126
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Handle Done button - apply selected date and close sheet
|
|
128
|
+
*/
|
|
129
|
+
const handleDone = () => {
|
|
130
|
+
onChange(tempDate);
|
|
131
|
+
close();
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Handle open - reset temp date to current value
|
|
136
|
+
*/
|
|
137
|
+
const handleOpen = () => {
|
|
138
|
+
setTempDate(value || new Date());
|
|
139
|
+
open();
|
|
140
|
+
};
|
|
141
|
+
|
|
127
142
|
/**
|
|
128
143
|
* Format date based on mode
|
|
129
144
|
* Uses native Date formatting (locale-aware)
|
|
@@ -182,7 +197,7 @@ export const AtomicDatePicker: React.FC<AtomicDatePickerProps> = ({
|
|
|
182
197
|
error ? styles.buttonError : undefined,
|
|
183
198
|
disabled ? styles.buttonDisabled : undefined,
|
|
184
199
|
]}
|
|
185
|
-
onPress={
|
|
200
|
+
onPress={handleOpen}
|
|
186
201
|
disabled={disabled}
|
|
187
202
|
testID={testID ? `${testID}-button` : undefined}
|
|
188
203
|
accessibilityLabel={label || placeholder}
|
|
@@ -211,49 +226,39 @@ export const AtomicDatePicker: React.FC<AtomicDatePickerProps> = ({
|
|
|
211
226
|
</Text>
|
|
212
227
|
)}
|
|
213
228
|
|
|
214
|
-
{/*
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
accessibilityLabel="Done"
|
|
248
|
-
accessibilityRole="button"
|
|
249
|
-
>
|
|
250
|
-
<Text style={styles.doneText}>Done</Text>
|
|
251
|
-
</TouchableOpacity>
|
|
252
|
-
</View>
|
|
253
|
-
</View>
|
|
254
|
-
</TouchableOpacity>
|
|
255
|
-
</Modal>
|
|
256
|
-
)}
|
|
229
|
+
{/* Bottom Sheet DatePicker */}
|
|
230
|
+
<BottomSheet
|
|
231
|
+
ref={sheetRef}
|
|
232
|
+
preset="medium"
|
|
233
|
+
enableBackdrop
|
|
234
|
+
enablePanDownToClose
|
|
235
|
+
enableHandleIndicator
|
|
236
|
+
onClose={() => {
|
|
237
|
+
// Reset temp date when closed without saving
|
|
238
|
+
setTempDate(value || new Date());
|
|
239
|
+
}}
|
|
240
|
+
>
|
|
241
|
+
<View style={styles.bottomSheetContent}>
|
|
242
|
+
<DateTimePicker
|
|
243
|
+
value={tempDate}
|
|
244
|
+
mode={mode}
|
|
245
|
+
display="spinner"
|
|
246
|
+
onChange={handleChange}
|
|
247
|
+
minimumDate={minimumDate}
|
|
248
|
+
maximumDate={maximumDate}
|
|
249
|
+
testID={testID ? `${testID}-picker` : undefined}
|
|
250
|
+
/>
|
|
251
|
+
<View style={styles.buttonContainer}>
|
|
252
|
+
<AtomicButton
|
|
253
|
+
label="Done"
|
|
254
|
+
onPress={handleDone}
|
|
255
|
+
variant="primary"
|
|
256
|
+
style={styles.doneButton}
|
|
257
|
+
testID={testID ? `${testID}-done` : undefined}
|
|
258
|
+
/>
|
|
259
|
+
</View>
|
|
260
|
+
</View>
|
|
261
|
+
</BottomSheet>
|
|
257
262
|
</View>
|
|
258
263
|
);
|
|
259
264
|
};
|
|
@@ -316,16 +321,9 @@ const getStyles = (
|
|
|
316
321
|
marginTop: tokens.spacing.xs,
|
|
317
322
|
marginLeft: tokens.spacing.xs,
|
|
318
323
|
},
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
justifyContent: 'flex-start',
|
|
323
|
-
},
|
|
324
|
-
pickerContainer: {
|
|
325
|
-
backgroundColor: tokens.colors.surface,
|
|
326
|
-
borderTopLeftRadius: tokens.borders.radius.xl,
|
|
327
|
-
borderTopRightRadius: tokens.borders.radius.xl,
|
|
328
|
-
paddingTop: tokens.spacing.lg,
|
|
324
|
+
bottomSheetContent: {
|
|
325
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
326
|
+
paddingTop: tokens.spacing.md,
|
|
329
327
|
paddingBottom: Math.max(
|
|
330
328
|
insets.bottom + tokens.spacing.md,
|
|
331
329
|
tokens.spacing.xl,
|
|
@@ -333,22 +331,11 @@ const getStyles = (
|
|
|
333
331
|
},
|
|
334
332
|
buttonContainer: {
|
|
335
333
|
alignItems: 'center',
|
|
336
|
-
marginTop: tokens.spacing.
|
|
337
|
-
paddingHorizontal: tokens.spacing.
|
|
334
|
+
marginTop: tokens.spacing.lg,
|
|
335
|
+
paddingHorizontal: tokens.spacing.md,
|
|
338
336
|
},
|
|
339
337
|
doneButton: {
|
|
340
|
-
backgroundColor: tokens.colors.primary,
|
|
341
|
-
paddingHorizontal: tokens.spacing.xl,
|
|
342
|
-
paddingVertical: tokens.spacing.sm,
|
|
343
|
-
borderRadius: tokens.borders.radius.lg,
|
|
344
338
|
minWidth: buttonMinWidth,
|
|
345
|
-
alignItems: 'center',
|
|
346
|
-
minHeight: 44, // Apple HIG minimum touch target
|
|
347
|
-
},
|
|
348
|
-
doneText: {
|
|
349
|
-
color: tokens.colors.onPrimary,
|
|
350
|
-
fontSize: tokens.typography.bodyLarge.fontSize,
|
|
351
|
-
fontWeight: tokens.typography.semibold,
|
|
352
339
|
},
|
|
353
340
|
});
|
|
354
341
|
};
|
|
@@ -1,53 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text } from 'react-native';
|
|
3
3
|
import { useAppDesignTokens } from '@umituz/react-native-theme';
|
|
4
|
+
import { getTextColor } from '@umituz/react-native-typography';
|
|
4
5
|
export const AtomicText = ({ children, type = 'bodyMedium', color, numberOfLines, ellipsizeMode, textAlign, style, testID, }) => {
|
|
5
6
|
const tokens = useAppDesignTokens();
|
|
6
7
|
// Get typography style from tokens
|
|
7
8
|
const typographyStyle = tokens.typography[type];
|
|
8
|
-
// Get color from tokens or use custom color
|
|
9
|
-
const
|
|
10
|
-
if (!color) {
|
|
11
|
-
return tokens.colors.textPrimary;
|
|
12
|
-
}
|
|
13
|
-
// Material Design 3 text color mapping
|
|
14
|
-
const colorMap = {
|
|
15
|
-
// General text colors (Material Design 3)
|
|
16
|
-
textPrimary: tokens.colors.textPrimary,
|
|
17
|
-
textSecondary: tokens.colors.textSecondary,
|
|
18
|
-
textTertiary: tokens.colors.textTertiary,
|
|
19
|
-
textDisabled: tokens.colors.textDisabled,
|
|
20
|
-
textInverse: tokens.colors.textInverse,
|
|
21
|
-
// Text on surfaces (Material Design 3)
|
|
22
|
-
onSurface: tokens.colors.onSurface,
|
|
23
|
-
onBackground: tokens.colors.onBackground,
|
|
24
|
-
// Text on colored backgrounds (Material Design 3)
|
|
25
|
-
onPrimary: tokens.colors.onPrimary,
|
|
26
|
-
onSecondary: tokens.colors.onSecondary,
|
|
27
|
-
onSuccess: tokens.colors.onSuccess,
|
|
28
|
-
onError: tokens.colors.onError,
|
|
29
|
-
onWarning: tokens.colors.onWarning,
|
|
30
|
-
onInfo: tokens.colors.onInfo,
|
|
31
|
-
// Semantic colors (can be used as text)
|
|
32
|
-
success: tokens.colors.success,
|
|
33
|
-
error: tokens.colors.error,
|
|
34
|
-
warning: tokens.colors.warning,
|
|
35
|
-
info: tokens.colors.info,
|
|
36
|
-
// Legacy support (deprecated - maps to new names)
|
|
37
|
-
primary: tokens.colors.textPrimary, // Legacy: use textPrimary or onPrimary
|
|
38
|
-
secondary: tokens.colors.textSecondary, // Legacy: use textSecondary or onSecondary
|
|
39
|
-
tertiary: tokens.colors.textTertiary, // Legacy: use textTertiary
|
|
40
|
-
disabled: tokens.colors.textDisabled, // Legacy: use textDisabled
|
|
41
|
-
inverse: tokens.colors.textInverse, // Legacy: use textInverse
|
|
42
|
-
// Legacy: surfaceVariant is a background color, but used as text - map to textSecondary
|
|
43
|
-
surfaceVariant: tokens.colors.textSecondary, // Legacy: use textSecondary instead
|
|
44
|
-
};
|
|
45
|
-
return colorMap[color] || color;
|
|
46
|
-
};
|
|
9
|
+
// Get color from tokens or use custom color using utility function
|
|
10
|
+
const resolvedColor = getTextColor(color, tokens);
|
|
47
11
|
const textStyle = [
|
|
48
12
|
typographyStyle,
|
|
49
13
|
{
|
|
50
|
-
color:
|
|
14
|
+
color: resolvedColor,
|
|
51
15
|
...(textAlign && { textAlign }),
|
|
52
16
|
},
|
|
53
17
|
style,
|
|
@@ -1,62 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text, StyleProp, TextStyle } from 'react-native';
|
|
3
3
|
import { useAppDesignTokens } from '@umituz/react-native-theme';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
| 'displayLarge' | 'displayMedium' | 'displaySmall'
|
|
7
|
-
| 'headlineLarge' | 'headlineMedium' | 'headlineSmall'
|
|
8
|
-
| 'titleLarge' | 'titleMedium' | 'titleSmall'
|
|
9
|
-
| 'bodyLarge' | 'bodyMedium' | 'bodySmall'
|
|
10
|
-
| 'labelLarge' | 'labelMedium' | 'labelSmall';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Material Design 3 Text Color Variants
|
|
14
|
-
*
|
|
15
|
-
* TEXT COLORS (for text on surfaces):
|
|
16
|
-
* - textPrimary, textSecondary, textTertiary: General text colors
|
|
17
|
-
* - onSurface, onBackground: Text on surface/background
|
|
18
|
-
*
|
|
19
|
-
* ON COLORS (for text on colored backgrounds):
|
|
20
|
-
* - onPrimary, onSecondary: Text on primary/secondary colored backgrounds
|
|
21
|
-
* - onSuccess, onError, onWarning, onInfo: Text on semantic colored backgrounds
|
|
22
|
-
*
|
|
23
|
-
* SEMANTIC COLORS (can be used as text colors):
|
|
24
|
-
* - success, error, warning, info: Semantic colors (can be text or background)
|
|
25
|
-
*
|
|
26
|
-
* NOTE: 'primary' and 'secondary' are BACKGROUND colors, not text colors.
|
|
27
|
-
* Use 'onPrimary'/'onSecondary' for text on colored backgrounds, or
|
|
28
|
-
* 'textPrimary'/'textSecondary' for general text.
|
|
29
|
-
*/
|
|
30
|
-
export type ColorVariant =
|
|
31
|
-
// General text colors (Material Design 3)
|
|
32
|
-
| 'textPrimary'
|
|
33
|
-
| 'textSecondary'
|
|
34
|
-
| 'textTertiary'
|
|
35
|
-
| 'textDisabled'
|
|
36
|
-
| 'textInverse'
|
|
37
|
-
// Text on surfaces (Material Design 3)
|
|
38
|
-
| 'onSurface'
|
|
39
|
-
| 'onBackground'
|
|
40
|
-
// Text on colored backgrounds (Material Design 3)
|
|
41
|
-
| 'onPrimary'
|
|
42
|
-
| 'onSecondary'
|
|
43
|
-
| 'onSuccess'
|
|
44
|
-
| 'onError'
|
|
45
|
-
| 'onWarning'
|
|
46
|
-
| 'onInfo'
|
|
47
|
-
// Semantic colors (can be used as text)
|
|
48
|
-
| 'success'
|
|
49
|
-
| 'error'
|
|
50
|
-
| 'warning'
|
|
51
|
-
| 'info'
|
|
52
|
-
// Legacy support (deprecated - use textPrimary/textSecondary instead)
|
|
53
|
-
| 'primary'
|
|
54
|
-
| 'secondary'
|
|
55
|
-
| 'tertiary'
|
|
56
|
-
| 'disabled'
|
|
57
|
-
| 'inverse'
|
|
58
|
-
// Legacy: surfaceVariant is a background color, maps to textSecondary
|
|
59
|
-
| 'surfaceVariant';
|
|
4
|
+
import type { TextStyleVariant, ColorVariant } from '@umituz/react-native-typography';
|
|
5
|
+
import { getTextColor } from '@umituz/react-native-typography';
|
|
60
6
|
|
|
61
7
|
export interface AtomicTextProps {
|
|
62
8
|
children: React.ReactNode;
|
|
@@ -84,56 +30,13 @@ export const AtomicText: React.FC<AtomicTextProps> = ({
|
|
|
84
30
|
// Get typography style from tokens
|
|
85
31
|
const typographyStyle = tokens.typography[type];
|
|
86
32
|
|
|
87
|
-
// Get color from tokens or use custom color
|
|
88
|
-
const
|
|
89
|
-
if (!color) {
|
|
90
|
-
return tokens.colors.textPrimary;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Material Design 3 text color mapping
|
|
94
|
-
const colorMap: Partial<Record<ColorVariant, string>> = {
|
|
95
|
-
// General text colors (Material Design 3)
|
|
96
|
-
textPrimary: tokens.colors.textPrimary,
|
|
97
|
-
textSecondary: tokens.colors.textSecondary,
|
|
98
|
-
textTertiary: tokens.colors.textTertiary,
|
|
99
|
-
textDisabled: tokens.colors.textDisabled,
|
|
100
|
-
textInverse: tokens.colors.textInverse,
|
|
101
|
-
|
|
102
|
-
// Text on surfaces (Material Design 3)
|
|
103
|
-
onSurface: tokens.colors.onSurface,
|
|
104
|
-
onBackground: tokens.colors.onBackground,
|
|
105
|
-
|
|
106
|
-
// Text on colored backgrounds (Material Design 3)
|
|
107
|
-
onPrimary: tokens.colors.onPrimary,
|
|
108
|
-
onSecondary: tokens.colors.onSecondary,
|
|
109
|
-
onSuccess: tokens.colors.onSuccess,
|
|
110
|
-
onError: tokens.colors.onError,
|
|
111
|
-
onWarning: tokens.colors.onWarning,
|
|
112
|
-
onInfo: tokens.colors.onInfo,
|
|
113
|
-
|
|
114
|
-
// Semantic colors (can be used as text)
|
|
115
|
-
success: tokens.colors.success,
|
|
116
|
-
error: tokens.colors.error,
|
|
117
|
-
warning: tokens.colors.warning,
|
|
118
|
-
info: tokens.colors.info,
|
|
119
|
-
|
|
120
|
-
// Legacy support (deprecated - maps to new names)
|
|
121
|
-
primary: tokens.colors.textPrimary, // Legacy: use textPrimary or onPrimary
|
|
122
|
-
secondary: tokens.colors.textSecondary, // Legacy: use textSecondary or onSecondary
|
|
123
|
-
tertiary: tokens.colors.textTertiary, // Legacy: use textTertiary
|
|
124
|
-
disabled: tokens.colors.textDisabled, // Legacy: use textDisabled
|
|
125
|
-
inverse: tokens.colors.textInverse, // Legacy: use textInverse
|
|
126
|
-
// Legacy: surfaceVariant is a background color, but used as text - map to textSecondary
|
|
127
|
-
surfaceVariant: tokens.colors.textSecondary, // Legacy: use textSecondary instead
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
return colorMap[color as ColorVariant] || color;
|
|
131
|
-
};
|
|
33
|
+
// Get color from tokens or use custom color using utility function
|
|
34
|
+
const resolvedColor = getTextColor(color, tokens);
|
|
132
35
|
|
|
133
36
|
const textStyle: StyleProp<TextStyle> = [
|
|
134
37
|
typographyStyle,
|
|
135
38
|
{
|
|
136
|
-
color:
|
|
39
|
+
color: resolvedColor,
|
|
137
40
|
...(textAlign && { textAlign }),
|
|
138
41
|
},
|
|
139
42
|
style,
|