@compsych/mobile-ui 1.0.19 → 1.0.21
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
|
@@ -2,13 +2,13 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Pressable,
|
|
5
|
+
ScrollView,
|
|
5
6
|
StyleProp,
|
|
6
7
|
StyleSheet,
|
|
7
|
-
View,
|
|
8
8
|
ViewStyle,
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { type IconName, SIZE_MAP, resolveIcon } from '../../icons';
|
|
12
12
|
import { useTheme } from '../../theme';
|
|
13
13
|
import { BodyText } from '../BodyText';
|
|
14
14
|
|
|
@@ -23,7 +23,6 @@ export interface SegmentedControlProps {
|
|
|
23
23
|
options: SegmentedControlOption[];
|
|
24
24
|
value: string;
|
|
25
25
|
onChange: (value: string) => void;
|
|
26
|
-
fullWidth?: boolean;
|
|
27
26
|
style?: StyleProp<ViewStyle>;
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -31,27 +30,19 @@ export function SegmentedControl({
|
|
|
31
30
|
options,
|
|
32
31
|
value,
|
|
33
32
|
onChange,
|
|
34
|
-
fullWidth = false,
|
|
35
33
|
style,
|
|
36
34
|
}: SegmentedControlProps) {
|
|
37
35
|
const { colorRoles: cr, dimensions: dim } = useTheme();
|
|
38
36
|
|
|
39
37
|
return (
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
borderWidth: dim.borderWidth.sysStrokeThin,
|
|
47
|
-
borderColor: cr.outline.sysOutline,
|
|
48
|
-
borderRadius: dim.borderRadius.sysRadiusFull,
|
|
49
|
-
padding: dim.spacing.padding.sysPadding4,
|
|
50
|
-
gap: dim.spacing.padding.sysPadding4,
|
|
51
|
-
},
|
|
52
|
-
fullWidth && styles.fullWidth,
|
|
53
|
-
style,
|
|
38
|
+
<ScrollView
|
|
39
|
+
horizontal
|
|
40
|
+
showsHorizontalScrollIndicator={false}
|
|
41
|
+
contentContainerStyle={[
|
|
42
|
+
styles.contentContainer,
|
|
43
|
+
{ gap: dim.spacing.padding.sysPadding4 },
|
|
54
44
|
]}
|
|
45
|
+
style={[styles.scroll, style]}
|
|
55
46
|
>
|
|
56
47
|
{options.map((option) => {
|
|
57
48
|
const isActive = option.value === value;
|
|
@@ -60,7 +51,8 @@ export function SegmentedControl({
|
|
|
60
51
|
const iconColor = isActive
|
|
61
52
|
? cr.accent.primary.sysOnPrimary
|
|
62
53
|
: cr.surface.surface.sysOnSurfaceVariant;
|
|
63
|
-
const IconComponent = option.icon ?
|
|
54
|
+
const IconComponent = option.icon ? resolveIcon(option.icon) : null;
|
|
55
|
+
const { size: iconPx, strokeWidth: iconSW } = SIZE_MAP['xsmall'];
|
|
64
56
|
|
|
65
57
|
return (
|
|
66
58
|
<Pressable
|
|
@@ -76,17 +68,21 @@ export function SegmentedControl({
|
|
|
76
68
|
paddingVertical: dim.spacing.padding.sysPadding6,
|
|
77
69
|
gap: dim.spacing.padding.sysPadding4,
|
|
78
70
|
borderRadius: dim.borderRadius.sysRadiusFull,
|
|
71
|
+
backgroundColor: isActive
|
|
72
|
+
? cr.accent.primary.sysPrimary
|
|
73
|
+
: cr.surface.surfaceContainer.sysSurfaceContainerHigh,
|
|
79
74
|
},
|
|
80
|
-
isActive && {
|
|
81
|
-
!isActive &&
|
|
82
|
-
pressed &&
|
|
83
|
-
!isDisabled && {
|
|
84
|
-
backgroundColor: cr.transparent.neutral.sysBlack10,
|
|
85
|
-
},
|
|
75
|
+
!isActive && pressed && !isDisabled && { opacity: 0.7 },
|
|
86
76
|
isDisabled && styles.disabled,
|
|
87
77
|
]}
|
|
88
78
|
>
|
|
89
|
-
{IconComponent &&
|
|
79
|
+
{IconComponent && (
|
|
80
|
+
<IconComponent
|
|
81
|
+
size={iconPx}
|
|
82
|
+
strokeWidth={iconSW}
|
|
83
|
+
color={iconColor}
|
|
84
|
+
/>
|
|
85
|
+
)}
|
|
90
86
|
<BodyText
|
|
91
87
|
variant="small"
|
|
92
88
|
emphasized={isActive}
|
|
@@ -98,27 +94,20 @@ export function SegmentedControl({
|
|
|
98
94
|
</Pressable>
|
|
99
95
|
);
|
|
100
96
|
})}
|
|
101
|
-
</
|
|
97
|
+
</ScrollView>
|
|
102
98
|
);
|
|
103
99
|
}
|
|
104
100
|
|
|
105
101
|
const styles = StyleSheet.create({
|
|
106
|
-
|
|
102
|
+
scroll: {
|
|
103
|
+
width: '100%',
|
|
104
|
+
},
|
|
105
|
+
contentContainer: {
|
|
107
106
|
flexDirection: 'row',
|
|
108
107
|
alignItems: 'center',
|
|
109
|
-
|
|
110
|
-
// Elevation/lv1: two Figma drop shadows combined into one RN shadow
|
|
111
|
-
shadowColor: '#000',
|
|
112
|
-
shadowOffset: { width: 0, height: 2 },
|
|
113
|
-
shadowOpacity: 0.08,
|
|
114
|
-
shadowRadius: 8,
|
|
115
|
-
elevation: 2,
|
|
116
|
-
},
|
|
117
|
-
fullWidth: {
|
|
118
|
-
alignSelf: 'stretch',
|
|
108
|
+
paddingVertical: 2,
|
|
119
109
|
},
|
|
120
110
|
item: {
|
|
121
|
-
flex: 1,
|
|
122
111
|
flexDirection: 'row',
|
|
123
112
|
alignItems: 'center',
|
|
124
113
|
justifyContent: 'center',
|
|
@@ -211,7 +211,8 @@ export function ServiceCard({
|
|
|
211
211
|
v.elevated && ELEVATION,
|
|
212
212
|
fullWidth && { alignSelf: 'stretch' as const },
|
|
213
213
|
isRow ? styles.rowRoot : styles.colRoot,
|
|
214
|
-
!isRow && { gap: s.gap },
|
|
214
|
+
!isRow && variant !== 'image' && { gap: s.gap },
|
|
215
|
+
variant === 'image' && { justifyContent: 'space-between' },
|
|
215
216
|
style,
|
|
216
217
|
];
|
|
217
218
|
|
|
@@ -294,13 +295,12 @@ export function ServiceCard({
|
|
|
294
295
|
resizeMode="cover"
|
|
295
296
|
accessible={false}
|
|
296
297
|
/>
|
|
297
|
-
<
|
|
298
|
+
<LinearGradient
|
|
299
|
+
colors={['rgba(0,0,0,0.4)', 'rgba(0,0,0,0.05)', 'rgba(0,0,0,0.5)']}
|
|
300
|
+
locations={[0.012, 0.268, 1]}
|
|
298
301
|
style={[
|
|
299
302
|
{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 },
|
|
300
|
-
{
|
|
301
|
-
borderRadius: s.borderRadius,
|
|
302
|
-
backgroundColor: 'rgba(0,0,0,0.30)',
|
|
303
|
-
},
|
|
303
|
+
{ borderRadius: s.borderRadius },
|
|
304
304
|
]}
|
|
305
305
|
pointerEvents="none"
|
|
306
306
|
/>
|
|
@@ -311,10 +311,14 @@ export function ServiceCard({
|
|
|
311
311
|
{renderedIcon}
|
|
312
312
|
</View>
|
|
313
313
|
)}
|
|
314
|
-
{
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
314
|
+
<View style={styles.imageBottom}>
|
|
315
|
+
<View style={{ flex: 1 }}>{textBlock}</View>
|
|
316
|
+
{onPress && ChevronRight && (
|
|
317
|
+
<View style={styles.imageArrowButton}>
|
|
318
|
+
<ChevronRight size={16} color={cr.surface.surface.sysOnSurface} strokeWidth={1.5} />
|
|
319
|
+
</View>
|
|
320
|
+
)}
|
|
321
|
+
</View>
|
|
318
322
|
{children}
|
|
319
323
|
</>
|
|
320
324
|
);
|
|
@@ -398,6 +402,21 @@ const styles = StyleSheet.create({
|
|
|
398
402
|
alignItems: 'center',
|
|
399
403
|
gap: 12,
|
|
400
404
|
},
|
|
405
|
+
imageBottom: {
|
|
406
|
+
flexDirection: 'row',
|
|
407
|
+
alignItems: 'flex-end',
|
|
408
|
+
width: '100%',
|
|
409
|
+
gap: 16,
|
|
410
|
+
},
|
|
411
|
+
imageArrowButton: {
|
|
412
|
+
width: 32,
|
|
413
|
+
height: 32,
|
|
414
|
+
borderRadius: 999,
|
|
415
|
+
backgroundColor: '#ffffff',
|
|
416
|
+
alignItems: 'center',
|
|
417
|
+
justifyContent: 'center',
|
|
418
|
+
flexShrink: 0,
|
|
419
|
+
},
|
|
401
420
|
rowTextBlock: {
|
|
402
421
|
flex: 1,
|
|
403
422
|
minWidth: 0,
|