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.
@@ -151,7 +151,7 @@ export const InputMessage: FC<InputMessageProps> = ({
151
151
  {replyToMessage?.content ?? ''}
152
152
  </Text>
153
153
  )}
154
- <TouchableOpacity onPress={onCancelReply} style={{ top: -8 }}>
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> = ({ onClosePress, onCopy, onEdit, onReportMessage, onPinToggle, isPinned }) => {
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
- <TouchableOpacity onPress={onClosePress}>
28
- <Ionicons name="close-outline" size={30} color={theme.text} />
29
- </TouchableOpacity>
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, Text } from 'react-native';
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> = ({ logo, onPress, onPressCity, onPressMap, onPressSpecialists, specialistsActive }) => {
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
- <Text>
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
- </Text>
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
+ };
@@ -9,6 +9,9 @@ const meta: Meta<typeof HeaderSwitcher> = {
9
9
  args: {
10
10
  isFirst: true,
11
11
  },
12
+ argTypes: {
13
+ background: { control: 'color' },
14
+ },
12
15
  };
13
16
 
14
17
  export default meta;
@@ -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: () => void;
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
- <TouchableOpacity onPress={onBackPress} accessibilityRole="button" accessibilityLabel={backAccessibilityLabel}>
68
- <Ionicons name="arrow-back" size={24} color={theme.text} />
69
- </TouchableOpacity>
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
- <TouchableOpacity onPress={onBack} disabled={!onBack}>
64
- <Ionicons size={24} name="arrow-back" color={theme.text} />
65
- </TouchableOpacity>
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) => (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-vs-lb",
3
- "version": "1.0.71",
3
+ "version": "1.0.73",
4
4
  "description": "Expo Router + Storybook template ready for npm distribution.",
5
5
  "keywords": [
6
6
  "expo",