rn-vs-lb 1.0.71 → 1.0.73
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/components/Chat/InputMessage.tsx +1 -1
- package/components/Header/HeaderEdit.stories.tsx +23 -1
- package/components/Header/HeaderEdit.tsx +21 -6
- package/components/Header/HeaderHome.stories.tsx +25 -1
- package/components/Header/HeaderHome.tsx +31 -7
- package/components/Header/HeaderSwitcher.stories.tsx +3 -0
- package/components/Header/HeaderSwitcher.tsx +3 -1
- package/components/Header/HeaderWithImg.stories.tsx +23 -1
- package/components/Header/HeaderWithImg.tsx +13 -5
- package/components/Profile/ProfileCard/ProfileCard.stories.tsx +14 -1
- package/components/Profile/ProfileCard/ProfileCard.tsx +9 -4
- package/package.json +1 -1
|
@@ -151,7 +151,7 @@ export const InputMessage: FC<InputMessageProps> = ({
|
|
|
151
151
|
{replyToMessage?.content ?? ''}
|
|
152
152
|
</Text>
|
|
153
153
|
)}
|
|
154
|
-
<TouchableOpacity onPress={onCancelReply} style={{ top:
|
|
154
|
+
<TouchableOpacity onPress={onCancelReply} style={{ top: 0 }}>
|
|
155
155
|
<Ionicons name="close-outline" size={25} color={theme.greyText} />
|
|
156
156
|
</TouchableOpacity>
|
|
157
157
|
</View>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Meta, StoryFn } from '@storybook/react';
|
|
3
|
-
import { View } from 'react-native';
|
|
3
|
+
import { Text, TouchableOpacity, View } from 'react-native';
|
|
4
4
|
import { HeaderEdit } from './HeaderEdit';
|
|
5
5
|
|
|
6
6
|
const meta: Meta = {
|
|
@@ -15,6 +15,8 @@ const meta: Meta = {
|
|
|
15
15
|
onReportMessage: { action: 'report' },
|
|
16
16
|
onPinToggle: { action: 'pin toggle' },
|
|
17
17
|
onEdit: { action: 'edit' },
|
|
18
|
+
customBackButton: { control: false },
|
|
19
|
+
background: { control: 'color' },
|
|
18
20
|
},
|
|
19
21
|
};
|
|
20
22
|
|
|
@@ -43,3 +45,23 @@ MinimalActions.args = {
|
|
|
43
45
|
onEdit: undefined,
|
|
44
46
|
isPinned: false,
|
|
45
47
|
};
|
|
48
|
+
|
|
49
|
+
export const WithCustomBackButton = Template.bind({});
|
|
50
|
+
WithCustomBackButton.args = {
|
|
51
|
+
background: '#FFF2E7',
|
|
52
|
+
};
|
|
53
|
+
WithCustomBackButton.render = (args) => (
|
|
54
|
+
<View style={{ padding: 16, backgroundColor: '#f8f8f8' }}>
|
|
55
|
+
<HeaderEdit
|
|
56
|
+
{...args}
|
|
57
|
+
customBackButton={(
|
|
58
|
+
<TouchableOpacity
|
|
59
|
+
onPress={args.onClosePress}
|
|
60
|
+
style={{ backgroundColor: '#FFE4CF', borderRadius: 12, paddingHorizontal: 10, paddingVertical: 6 }}
|
|
61
|
+
>
|
|
62
|
+
<Text style={{ fontSize: 12, fontWeight: '600' }}>{'< Close'}</Text>
|
|
63
|
+
</TouchableOpacity>
|
|
64
|
+
)}
|
|
65
|
+
/>
|
|
66
|
+
</View>
|
|
67
|
+
);
|
|
@@ -10,9 +10,20 @@ interface HeaderProps {
|
|
|
10
10
|
onReportMessage: () => void;
|
|
11
11
|
onPinToggle: () => void;
|
|
12
12
|
isPinned: boolean;
|
|
13
|
+
background?: string;
|
|
14
|
+
customBackButton?: React.ReactNode;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export const HeaderEdit: React.FC<HeaderProps> = ({
|
|
17
|
+
export const HeaderEdit: React.FC<HeaderProps> = ({
|
|
18
|
+
onClosePress,
|
|
19
|
+
onCopy,
|
|
20
|
+
onEdit,
|
|
21
|
+
onReportMessage,
|
|
22
|
+
onPinToggle,
|
|
23
|
+
isPinned,
|
|
24
|
+
background,
|
|
25
|
+
customBackButton,
|
|
26
|
+
}) => {
|
|
16
27
|
const { globalStyleSheet, theme, sizes, commonStyles } = useTheme();
|
|
17
28
|
const styles = getStyles({ globalStyleSheet, theme, sizes, commonStyles });
|
|
18
29
|
|
|
@@ -22,11 +33,15 @@ export const HeaderEdit: React.FC<HeaderProps> = ({ onClosePress, onCopy, onEdit
|
|
|
22
33
|
onPress={(e) => {
|
|
23
34
|
e.stopPropagation();
|
|
24
35
|
}}
|
|
25
|
-
style={styles.container}
|
|
36
|
+
style={[styles.container, background ? { backgroundColor: background } : undefined]}
|
|
26
37
|
>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
{customBackButton ? (
|
|
39
|
+
customBackButton
|
|
40
|
+
) : (
|
|
41
|
+
<TouchableOpacity onPress={onClosePress}>
|
|
42
|
+
<Ionicons name="close-outline" size={30} color={theme.text} />
|
|
43
|
+
</TouchableOpacity>
|
|
44
|
+
)}
|
|
30
45
|
<View style={[styles.titleContainer]}>
|
|
31
46
|
<TouchableOpacity onPress={onReportMessage}>
|
|
32
47
|
<Ionicons name="megaphone-outline" size={25} color={theme.red} />
|
|
@@ -71,4 +86,4 @@ const getStyles = ({ theme, sizes, globalStyleSheet, commonStyles }: { commonSty
|
|
|
71
86
|
gap: 22,
|
|
72
87
|
...globalStyleSheet.flexRowEnd,
|
|
73
88
|
},
|
|
74
|
-
});
|
|
89
|
+
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Meta, StoryObj } from '@storybook/react';
|
|
3
|
-
import { Text, View } from 'react-native';
|
|
3
|
+
import { Text, TouchableOpacity, View } from 'react-native';
|
|
4
4
|
import { HeaderHome } from './HeaderHome';
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof HeaderHome> = {
|
|
7
7
|
title: 'Layout/Header/HeaderHome',
|
|
8
8
|
component: HeaderHome,
|
|
9
9
|
argTypes: {
|
|
10
|
+
onBackPress: { action: 'back press' },
|
|
10
11
|
onPress: { action: 'header press' },
|
|
11
12
|
onPressCity: { action: 'city press' },
|
|
12
13
|
onPressMap: { action: 'map press' },
|
|
13
14
|
onPressSpecialists: { action: 'specialists press' },
|
|
15
|
+
customBackButton: { control: false },
|
|
16
|
+
background: { control: 'color' },
|
|
14
17
|
},
|
|
15
18
|
};
|
|
16
19
|
|
|
@@ -61,3 +64,24 @@ export const SpecialistsToggle: Story = {
|
|
|
61
64
|
<Text style={{ fontWeight: '600', fontSize: 18 }}>Experts</Text>,
|
|
62
65
|
),
|
|
63
66
|
};
|
|
67
|
+
|
|
68
|
+
export const WithCustomBackButton: Story = {
|
|
69
|
+
args: {
|
|
70
|
+
background: '#EEF8EE',
|
|
71
|
+
},
|
|
72
|
+
render: (args) =>
|
|
73
|
+
renderWithLogo(
|
|
74
|
+
{
|
|
75
|
+
...args,
|
|
76
|
+
customBackButton: (
|
|
77
|
+
<TouchableOpacity
|
|
78
|
+
onPress={args.onBackPress}
|
|
79
|
+
style={{ backgroundColor: '#DDF1DD', borderRadius: 12, paddingHorizontal: 10, paddingVertical: 6, marginRight: 8 }}
|
|
80
|
+
>
|
|
81
|
+
<Text style={{ fontSize: 12, fontWeight: '600' }}>{'< Back'}</Text>
|
|
82
|
+
</TouchableOpacity>
|
|
83
|
+
),
|
|
84
|
+
},
|
|
85
|
+
<Text style={{ fontWeight: '600', fontSize: 18 }}>Experts</Text>,
|
|
86
|
+
),
|
|
87
|
+
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { View, TouchableOpacity
|
|
1
|
+
import { View, TouchableOpacity } from 'react-native';
|
|
2
2
|
import React, { FC, ReactNode } from 'react';
|
|
3
3
|
import { Ionicons, FontAwesome5 } from '@expo/vector-icons';
|
|
4
4
|
import { useTheme } from '../../theme';
|
|
5
5
|
|
|
6
6
|
interface HeaderHomeProps {
|
|
7
7
|
logo: ReactNode;
|
|
8
|
+
onBackPress?: () => void;
|
|
9
|
+
customBackButton?: ReactNode;
|
|
10
|
+
background?: string;
|
|
8
11
|
onPress?: () => void;
|
|
9
12
|
onPressCity?: () => void;
|
|
10
13
|
onPressMap?: () => void;
|
|
@@ -12,15 +15,36 @@ interface HeaderHomeProps {
|
|
|
12
15
|
specialistsActive?: boolean;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
export const HeaderHome: FC<HeaderHomeProps> = ({
|
|
18
|
+
export const HeaderHome: FC<HeaderHomeProps> = ({
|
|
19
|
+
logo,
|
|
20
|
+
onBackPress,
|
|
21
|
+
customBackButton,
|
|
22
|
+
background,
|
|
23
|
+
onPress,
|
|
24
|
+
onPressCity,
|
|
25
|
+
onPressMap,
|
|
26
|
+
onPressSpecialists,
|
|
27
|
+
specialistsActive,
|
|
28
|
+
}) => {
|
|
16
29
|
const { globalStyleSheet, theme, commonStyles } = useTheme();
|
|
30
|
+
const shouldShowBack = Boolean(customBackButton || onBackPress);
|
|
17
31
|
|
|
18
32
|
return (
|
|
19
|
-
<View style={[globalStyleSheet.flexRowCenterBetween, { height: 50 }]}>
|
|
20
|
-
<View>
|
|
21
|
-
|
|
33
|
+
<View style={[globalStyleSheet.flexRowCenterBetween, { height: 50, backgroundColor: background }]}>
|
|
34
|
+
<View style={[globalStyleSheet.flexRowCenter]}>
|
|
35
|
+
{shouldShowBack && (
|
|
36
|
+
customBackButton ?? (
|
|
37
|
+
<TouchableOpacity
|
|
38
|
+
style={[commonStyles.btnicon, { marginRight: 8 }]}
|
|
39
|
+
onPress={onBackPress}
|
|
40
|
+
>
|
|
41
|
+
<Ionicons name="arrow-back" size={22} color={theme.text} />
|
|
42
|
+
</TouchableOpacity>
|
|
43
|
+
)
|
|
44
|
+
)}
|
|
45
|
+
<View>
|
|
22
46
|
{logo}
|
|
23
|
-
</
|
|
47
|
+
</View>
|
|
24
48
|
</View>
|
|
25
49
|
{(onPress || onPressCity || onPressMap || onPressSpecialists) && (
|
|
26
50
|
<View style={{ flexDirection: 'row' }}>
|
|
@@ -60,4 +84,4 @@ export const HeaderHome: FC<HeaderHomeProps> = ({ logo, onPress, onPressCity, on
|
|
|
60
84
|
)}
|
|
61
85
|
</View>
|
|
62
86
|
);
|
|
63
|
-
};
|
|
87
|
+
};
|
|
@@ -5,9 +5,10 @@ interface HeaderSwitcherProps {
|
|
|
5
5
|
isFirst: boolean;
|
|
6
6
|
componentA: React.ReactElement;
|
|
7
7
|
componentB: React.ReactElement;
|
|
8
|
+
background?: string;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export const HeaderSwitcher: React.FC<HeaderSwitcherProps> = ({ isFirst, componentA, componentB }) => {
|
|
11
|
+
export const HeaderSwitcher: React.FC<HeaderSwitcherProps> = ({ isFirst, componentA, componentB, background }) => {
|
|
11
12
|
const [currentComponent, setCurrentComponent] = useState<React.ReactElement>(isFirst ? componentA : componentB);
|
|
12
13
|
const opacity = useRef(new Animated.Value(1)).current;
|
|
13
14
|
|
|
@@ -30,6 +31,7 @@ export const HeaderSwitcher: React.FC<HeaderSwitcherProps> = ({ isFirst, compone
|
|
|
30
31
|
<Animated.View
|
|
31
32
|
style={[
|
|
32
33
|
styles.animatedContainer,
|
|
34
|
+
background ? { backgroundColor: background } : undefined,
|
|
33
35
|
{ opacity }
|
|
34
36
|
]}
|
|
35
37
|
pointerEvents="box-none" // ⚠️ пропускает касания дальше
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Meta, StoryFn } from '@storybook/react';
|
|
3
|
-
import { View } from 'react-native';
|
|
3
|
+
import { Text, TouchableOpacity, View } from 'react-native';
|
|
4
4
|
import HeaderWithImg from './HeaderWithImg';
|
|
5
5
|
|
|
6
6
|
const meta: Meta = {
|
|
@@ -30,6 +30,8 @@ const meta: Meta = {
|
|
|
30
30
|
onBackPress: { action: 'back' },
|
|
31
31
|
onImgPress: { action: 'avatar press' },
|
|
32
32
|
onActionPress: { action: 'action press' },
|
|
33
|
+
customBackButton: { control: false },
|
|
34
|
+
background: { control: 'color' },
|
|
33
35
|
},
|
|
34
36
|
};
|
|
35
37
|
|
|
@@ -91,3 +93,23 @@ OfflineUser.args = {
|
|
|
91
93
|
{ _id: '1', userName: 'Taylor Smith' },
|
|
92
94
|
],
|
|
93
95
|
};
|
|
96
|
+
|
|
97
|
+
export const WithCustomBackButton = Template.bind({});
|
|
98
|
+
WithCustomBackButton.args = {
|
|
99
|
+
background: '#EAF5FF',
|
|
100
|
+
};
|
|
101
|
+
WithCustomBackButton.render = (args) => (
|
|
102
|
+
<View style={{ padding: 16, backgroundColor: '#f2f2f2' }}>
|
|
103
|
+
<HeaderWithImg
|
|
104
|
+
{...args}
|
|
105
|
+
customBackButton={(
|
|
106
|
+
<TouchableOpacity
|
|
107
|
+
onPress={args.onBackPress}
|
|
108
|
+
style={{ backgroundColor: '#D7E9FF', borderRadius: 12, paddingHorizontal: 10, paddingVertical: 6 }}
|
|
109
|
+
>
|
|
110
|
+
<Text style={{ fontSize: 12, fontWeight: '600' }}>{'< Back'}</Text>
|
|
111
|
+
</TouchableOpacity>
|
|
112
|
+
)}
|
|
113
|
+
/>
|
|
114
|
+
</View>
|
|
115
|
+
);
|
|
@@ -14,7 +14,9 @@ interface HeaderProps {
|
|
|
14
14
|
title: string;
|
|
15
15
|
onImgPress: () => void;
|
|
16
16
|
onActionPress?: () => void;
|
|
17
|
-
onBackPress
|
|
17
|
+
onBackPress?: () => void;
|
|
18
|
+
customBackButton?: React.ReactNode;
|
|
19
|
+
background?: string;
|
|
18
20
|
isGroupChat: boolean;
|
|
19
21
|
users: ChatUser[];
|
|
20
22
|
|
|
@@ -39,6 +41,8 @@ const HeaderWithImg: React.FC<HeaderProps> = ({
|
|
|
39
41
|
onImgPress,
|
|
40
42
|
onActionPress,
|
|
41
43
|
onBackPress,
|
|
44
|
+
customBackButton,
|
|
45
|
+
background,
|
|
42
46
|
isGroupChat,
|
|
43
47
|
users,
|
|
44
48
|
isOnline = false,
|
|
@@ -63,10 +67,14 @@ const HeaderWithImg: React.FC<HeaderProps> = ({
|
|
|
63
67
|
const singleUser = users?.[0];
|
|
64
68
|
|
|
65
69
|
return (
|
|
66
|
-
<View style={styles.container}>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
<View style={[styles.container, background ? { backgroundColor: background } : undefined]}>
|
|
71
|
+
{customBackButton ? (
|
|
72
|
+
customBackButton
|
|
73
|
+
) : (
|
|
74
|
+
<TouchableOpacity onPress={onBackPress} accessibilityRole="button" accessibilityLabel={backAccessibilityLabel}>
|
|
75
|
+
<Ionicons name="arrow-back" size={24} color={theme.text} />
|
|
76
|
+
</TouchableOpacity>
|
|
77
|
+
)}
|
|
70
78
|
|
|
71
79
|
<View style={styles.title}>
|
|
72
80
|
<View style={globalStyleSheet.flexRowCenterBetween}>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// stories/Profile/PureProfileCard.stories.tsx
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { View } from 'react-native';
|
|
4
|
+
import { Text, TouchableOpacity, View } from 'react-native';
|
|
5
5
|
import { FontAwesome, FontAwesome5, FontAwesome6, Ionicons, MaterialIcons, Octicons } from '@expo/vector-icons';
|
|
6
6
|
import PureProfileCard from "./ProfileCard";
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ const meta = {
|
|
|
11
11
|
argTypes: {
|
|
12
12
|
onBack: { action: 'onBack' },
|
|
13
13
|
onLearnMorePress: { action: 'onLearnMorePress' },
|
|
14
|
+
customBackButton: { control: false },
|
|
14
15
|
},
|
|
15
16
|
decorators: [
|
|
16
17
|
// если у тебя есть ThemeProvider — оберни им здесь
|
|
@@ -136,3 +137,15 @@ export const SixHeaderActions: S = {
|
|
|
136
137
|
],
|
|
137
138
|
},
|
|
138
139
|
};
|
|
140
|
+
|
|
141
|
+
export const WithCustomBackButton: S = {
|
|
142
|
+
args: {
|
|
143
|
+
customBackButton: (
|
|
144
|
+
<TouchableOpacity
|
|
145
|
+
style={{ backgroundColor: '#D7E9FF', borderRadius: 12, paddingHorizontal: 10, paddingVertical: 6 }}
|
|
146
|
+
>
|
|
147
|
+
<Text style={{ fontSize: 12, fontWeight: '600' }}>{'< Back'}</Text>
|
|
148
|
+
</TouchableOpacity>
|
|
149
|
+
),
|
|
150
|
+
},
|
|
151
|
+
};
|
|
@@ -36,6 +36,7 @@ export type PureProfileCardProps = {
|
|
|
36
36
|
|
|
37
37
|
/** действия/навигация */
|
|
38
38
|
onBack?: () => void;
|
|
39
|
+
customBackButton?: React.ReactNode;
|
|
39
40
|
headerActions?: PureProfileCardHeaderAction[];
|
|
40
41
|
|
|
41
42
|
/** CTA */
|
|
@@ -47,7 +48,7 @@ export default function PureProfileCard(props: PureProfileCardProps) {
|
|
|
47
48
|
const {
|
|
48
49
|
name, imageUri,
|
|
49
50
|
isAuth, isMe, isOnline, lastSeenText,
|
|
50
|
-
onBack, headerActions,
|
|
51
|
+
onBack, customBackButton, headerActions,
|
|
51
52
|
onLearnMorePress, ctaActions,
|
|
52
53
|
} = props;
|
|
53
54
|
|
|
@@ -60,9 +61,13 @@ export default function PureProfileCard(props: PureProfileCardProps) {
|
|
|
60
61
|
<View style={styles.cardContainer}>
|
|
61
62
|
{/* навбар */}
|
|
62
63
|
<View style={[globalStyleSheet.flexRowCenterBetween, styles.navigation]}>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
{customBackButton ? (
|
|
65
|
+
customBackButton
|
|
66
|
+
) : (
|
|
67
|
+
<TouchableOpacity onPress={onBack} disabled={!onBack}>
|
|
68
|
+
<Ionicons size={24} name="arrow-back" color={theme.text} />
|
|
69
|
+
</TouchableOpacity>
|
|
70
|
+
)}
|
|
66
71
|
|
|
67
72
|
<View style={styles.settingSection}>
|
|
68
73
|
{visibleHeaderActions.map((action, index) => (
|