rn-vs-lb 1.0.66 → 1.0.67
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/README.md +1 -0
- package/components/Chat/InputMessage.tsx +2 -1
- package/components/Chat/MessageItem/LinkyText.tsx +9 -1
- package/components/Chat/MessageItem/styles.ts +3 -0
- package/components/Modals/ReportModal.tsx +1 -1
- package/components/Screens/HoroscopeScreen.stories.tsx +299 -0
- package/index.ts +1 -0
- package/package.json +2 -1
- package/theme/index.ts +2 -0
package/README.md
CHANGED
|
@@ -78,5 +78,6 @@ yarn build-storybook
|
|
|
78
78
|
6. **Опубликуйте релиз**. Убедившись, что версия не занята, выполните:
|
|
79
79
|
```sh
|
|
80
80
|
npm publish --access public
|
|
81
|
+
npm publish --access public --otp=RECOVERY_CODE
|
|
81
82
|
```
|
|
82
83
|
7. **Проверьте публикацию**. После успешной публикации обновите теги в git (`git tag vX.Y.Z && git push --tags`) и убедитесь, что пакет появился на npmjs.com.
|
|
@@ -265,11 +265,12 @@ export const getStyles = (theme: ThemeType) =>
|
|
|
265
265
|
paddingHorizontal: 10,
|
|
266
266
|
paddingVertical: 6,
|
|
267
267
|
borderRadius: 4,
|
|
268
|
+
top:4,
|
|
268
269
|
borderColor: theme.white,
|
|
269
270
|
},
|
|
270
271
|
sendButton: {
|
|
271
272
|
position: 'absolute',
|
|
272
|
-
bottom:
|
|
273
|
+
bottom: 8,
|
|
273
274
|
right: 8,
|
|
274
275
|
borderRadius: 4,
|
|
275
276
|
justifyContent: 'center',
|
|
@@ -3,6 +3,7 @@ import React, { FC, useMemo } from 'react';
|
|
|
3
3
|
import { Text } from 'react-native';
|
|
4
4
|
import { ThemeType } from '../../../theme';
|
|
5
5
|
import { getStyles } from './styles';
|
|
6
|
+
import { formatBoldText } from '../../../utils';
|
|
6
7
|
|
|
7
8
|
interface LinkyTextProps {
|
|
8
9
|
text: string;
|
|
@@ -21,6 +22,13 @@ export const LinkyText: FC<LinkyTextProps> = ({ text, theme, onLinkPress, onLong
|
|
|
21
22
|
onLinkPress?.(url);
|
|
22
23
|
};
|
|
23
24
|
|
|
25
|
+
const renderBoldParts = (segment: string, keyPrefix: string) =>
|
|
26
|
+
formatBoldText(segment).map((part, index) => (
|
|
27
|
+
<Text key={`${keyPrefix}-${index}`} style={part.bold ? styles.messageTextBold : undefined}>
|
|
28
|
+
{part.text}
|
|
29
|
+
</Text>
|
|
30
|
+
));
|
|
31
|
+
|
|
24
32
|
return (
|
|
25
33
|
<Text style={styles.messageText}>
|
|
26
34
|
{parts.map((part, i) =>
|
|
@@ -35,7 +43,7 @@ export const LinkyText: FC<LinkyTextProps> = ({ text, theme, onLinkPress, onLong
|
|
|
35
43
|
{part}
|
|
36
44
|
</Text>
|
|
37
45
|
) : (
|
|
38
|
-
|
|
46
|
+
renderBoldParts(part, `text-${i}`)
|
|
39
47
|
)
|
|
40
48
|
)}
|
|
41
49
|
</Text>
|
|
@@ -62,7 +62,7 @@ const ReportModal: React.FC<Props> = ({
|
|
|
62
62
|
<View style={styles.container}>
|
|
63
63
|
<Text style={styles.title}>{title}</Text>
|
|
64
64
|
<ScrollView style={styles.reasonsContainer}>
|
|
65
|
-
{reasons
|
|
65
|
+
{reasons?.map((reason) => (
|
|
66
66
|
<TouchableOpacity
|
|
67
67
|
key={reason}
|
|
68
68
|
style={[
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { Meta, StoryFn } from '@storybook/react';
|
|
3
|
+
import { FlatList, ScrollView, StyleSheet, Text, View } from 'react-native';
|
|
4
|
+
import { Feather, MaterialCommunityIcons } from '@expo/vector-icons';
|
|
5
|
+
|
|
6
|
+
import { ThemeProvider, createAppTheme, useTheme } from '../../theme';
|
|
7
|
+
import HeaderDefault from '../Header/HeaderDefault';
|
|
8
|
+
import TabBar from '../UI/TabBar/TabBarAi';
|
|
9
|
+
import { darkTheme, SIZES } from '../../theme/theme';
|
|
10
|
+
import { HeaderHome } from '../Header';
|
|
11
|
+
|
|
12
|
+
const darkAppTheme = createAppTheme({
|
|
13
|
+
light: darkTheme,
|
|
14
|
+
dark: darkTheme,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const previewStyles = StyleSheet.create({
|
|
18
|
+
previewBackground: {
|
|
19
|
+
flex: 1,
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
paddingVertical: 48,
|
|
23
|
+
backgroundColor: '#050A1B',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const meta: Meta = {
|
|
28
|
+
title: 'Screens/Horoscope/DailyOverview',
|
|
29
|
+
component: () => null,
|
|
30
|
+
decorators: [
|
|
31
|
+
(Story) => (
|
|
32
|
+
<ThemeProvider theme={darkAppTheme}>
|
|
33
|
+
<View style={previewStyles.previewBackground}>
|
|
34
|
+
<Story />
|
|
35
|
+
</View>
|
|
36
|
+
</ThemeProvider>
|
|
37
|
+
),
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default meta;
|
|
42
|
+
|
|
43
|
+
type Story = StoryFn;
|
|
44
|
+
|
|
45
|
+
type HoroscopeCardData = {
|
|
46
|
+
key: string;
|
|
47
|
+
title: string;
|
|
48
|
+
description: string;
|
|
49
|
+
icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];
|
|
50
|
+
accent: string;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const cards: HoroscopeCardData[] = [
|
|
54
|
+
{
|
|
55
|
+
key: 'career',
|
|
56
|
+
title: 'Карьера',
|
|
57
|
+
description:
|
|
58
|
+
'Луна во Льве помогает сфокусироваться на долгосрочных целях и заметить новые возможности роста.',
|
|
59
|
+
icon: 'briefcase-variant-outline',
|
|
60
|
+
accent: '#63B3FF',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
key: 'love',
|
|
64
|
+
title: 'Любовь',
|
|
65
|
+
description:
|
|
66
|
+
'В отношениях сегодня больше тепла. Откровенный разговор сделает связь сильнее.',
|
|
67
|
+
icon: 'heart-outline',
|
|
68
|
+
accent: '#FF7AB8',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: 'health',
|
|
72
|
+
title: 'Здоровье',
|
|
73
|
+
description:
|
|
74
|
+
'Добавьте к привычному распорядку короткую разминку — организм отблагодарит энергией.',
|
|
75
|
+
icon: 'heart-pulse',
|
|
76
|
+
accent: '#7DE2AC',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
key: 'family',
|
|
80
|
+
title: 'Семья',
|
|
81
|
+
description:
|
|
82
|
+
'Совместный вечер укрепит доверие. Запланируйте семейный ритуал, чтобы повторить его позже.',
|
|
83
|
+
icon: 'account-group-outline',
|
|
84
|
+
accent: '#F7C977',
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const tabs = [
|
|
89
|
+
{ key: 'yesterday', label: 'Вчера' },
|
|
90
|
+
{ key: 'today', label: 'Сегодня' },
|
|
91
|
+
{ key: 'tomorrow', label: 'Завтра' },
|
|
92
|
+
{ key: 'week', label: 'На неделю' },
|
|
93
|
+
{ key: 'month', label: 'На месяц' },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const ScreenSurface: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
97
|
+
const { theme, sizes } = useTheme();
|
|
98
|
+
const surfaceStyles = useMemo(
|
|
99
|
+
() =>
|
|
100
|
+
StyleSheet.create({
|
|
101
|
+
surface: {
|
|
102
|
+
backgroundColor: theme.background,
|
|
103
|
+
borderRadius: sizes.radius_lg as number,
|
|
104
|
+
paddingHorizontal: sizes.xs as number,
|
|
105
|
+
paddingVertical: sizes.xs as number,
|
|
106
|
+
width: 360,
|
|
107
|
+
minHeight: 640,
|
|
108
|
+
gap: sizes.lg as number,
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
[theme, sizes],
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return <View style={surfaceStyles.surface}>{children}</View>;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const HoroscopeDescription: React.FC = () => {
|
|
118
|
+
const { theme, sizes, typography } = useTheme();
|
|
119
|
+
const styles = useMemo(
|
|
120
|
+
() =>
|
|
121
|
+
StyleSheet.create({
|
|
122
|
+
container: {
|
|
123
|
+
backgroundColor: theme.card,
|
|
124
|
+
borderRadius: sizes.radius_lg as number,
|
|
125
|
+
paddingHorizontal: sizes.lg as number,
|
|
126
|
+
paddingVertical: sizes.lg as number,
|
|
127
|
+
gap: sizes.sm as number,
|
|
128
|
+
},
|
|
129
|
+
title: {
|
|
130
|
+
...typography.titleH5,
|
|
131
|
+
},
|
|
132
|
+
text: {
|
|
133
|
+
...typography.body,
|
|
134
|
+
lineHeight: 20,
|
|
135
|
+
},
|
|
136
|
+
}),
|
|
137
|
+
[theme, sizes, typography],
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<View style={styles.container}>
|
|
142
|
+
<Text style={styles.title}>Понедельник, 10 ноября</Text>
|
|
143
|
+
<Text style={styles.text}>
|
|
144
|
+
Сегодня, Козерог, энергия Луны во Льве помогает смело заявить о себе. Используйте этот заряд, чтобы показать
|
|
145
|
+
свои идеи и таланты, а также поддержать тех, кто рядом с вами.
|
|
146
|
+
</Text>
|
|
147
|
+
<Text style={styles.text}>
|
|
148
|
+
День отлично подходит для проектов, что зажигают вас изнутри. Делитесь вдохновением и не бойтесь инициативы —
|
|
149
|
+
это поможет получить заслуженное внимание.
|
|
150
|
+
</Text>
|
|
151
|
+
</View>
|
|
152
|
+
);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const CARD_WIDTH = 280;
|
|
156
|
+
|
|
157
|
+
const HoroscopeCard: React.FC<{ item: HoroscopeCardData }> = ({ item }) => {
|
|
158
|
+
const { theme, sizes, typography } = useTheme();
|
|
159
|
+
const styles = useMemo(
|
|
160
|
+
() =>
|
|
161
|
+
StyleSheet.create({
|
|
162
|
+
card: {
|
|
163
|
+
backgroundColor: theme.card,
|
|
164
|
+
borderRadius: sizes.radius_lg as number,
|
|
165
|
+
padding: sizes.lg as number,
|
|
166
|
+
width: CARD_WIDTH,
|
|
167
|
+
minHeight: 156,
|
|
168
|
+
justifyContent: 'space-between',
|
|
169
|
+
},
|
|
170
|
+
header: {
|
|
171
|
+
flexDirection: 'row',
|
|
172
|
+
justifyContent: 'space-between',
|
|
173
|
+
alignItems: 'flex-start',
|
|
174
|
+
},
|
|
175
|
+
iconWrapper: {
|
|
176
|
+
backgroundColor: item.accent,
|
|
177
|
+
borderRadius: sizes.radius as number,
|
|
178
|
+
padding: sizes.sm as number,
|
|
179
|
+
},
|
|
180
|
+
title: {
|
|
181
|
+
marginTop: sizes.sm as number,
|
|
182
|
+
...typography.titleH6,
|
|
183
|
+
},
|
|
184
|
+
description: {
|
|
185
|
+
marginTop: sizes.xs as number,
|
|
186
|
+
...typography.body,
|
|
187
|
+
},
|
|
188
|
+
}),
|
|
189
|
+
[theme, sizes, typography, item.accent],
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<View style={styles.card}>
|
|
194
|
+
<View style={styles.header}>
|
|
195
|
+
<View style={styles.iconWrapper}>
|
|
196
|
+
<MaterialCommunityIcons name={item.icon} size={24} color={theme.background} />
|
|
197
|
+
</View>
|
|
198
|
+
<Feather name="lock" size={18} color={theme.greyText} />
|
|
199
|
+
</View>
|
|
200
|
+
<Text style={styles.title}>{item.title}</Text>
|
|
201
|
+
<Text numberOfLines={3} style={styles.description}>
|
|
202
|
+
{item.description}
|
|
203
|
+
</Text>
|
|
204
|
+
</View>
|
|
205
|
+
);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const HoroscopeCardsCarousel: React.FC = () => {
|
|
209
|
+
const { sizes } = useTheme();
|
|
210
|
+
const GAP = 16;
|
|
211
|
+
const contentPad = 0;
|
|
212
|
+
|
|
213
|
+
const getItemLayout = (_: unknown, index: number) => ({
|
|
214
|
+
length: CARD_WIDTH + GAP,
|
|
215
|
+
offset: (CARD_WIDTH + GAP) * index + contentPad,
|
|
216
|
+
index,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<FlatList
|
|
221
|
+
horizontal
|
|
222
|
+
data={cards}
|
|
223
|
+
keyExtractor={(it) => it.key}
|
|
224
|
+
showsHorizontalScrollIndicator={false}
|
|
225
|
+
contentContainerStyle={{ paddingHorizontal: contentPad }}
|
|
226
|
+
ItemSeparatorComponent={() => <View style={{ width: GAP }} />}
|
|
227
|
+
renderItem={({ item }) => <HoroscopeCard item={item} />}
|
|
228
|
+
getItemLayout={getItemLayout}
|
|
229
|
+
snapToAlignment="start"
|
|
230
|
+
decelerationRate="fast"
|
|
231
|
+
snapToInterval={CARD_WIDTH + GAP}
|
|
232
|
+
/>
|
|
233
|
+
);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const HoroscopeTabBar: React.FC<{
|
|
237
|
+
activeIndex: number;
|
|
238
|
+
onChange: (index: number) => void;
|
|
239
|
+
}> = ({ activeIndex, onChange }) => {
|
|
240
|
+
const { theme } = useTheme();
|
|
241
|
+
const styles = useMemo(
|
|
242
|
+
() =>
|
|
243
|
+
StyleSheet.create({
|
|
244
|
+
wrapper: {
|
|
245
|
+
backgroundColor: 'transparent',
|
|
246
|
+
paddingVertical: 4,
|
|
247
|
+
},
|
|
248
|
+
divider: {
|
|
249
|
+
height: 1,
|
|
250
|
+
backgroundColor: theme.border,
|
|
251
|
+
marginTop: 8,
|
|
252
|
+
},
|
|
253
|
+
}),
|
|
254
|
+
[theme],
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<View>
|
|
259
|
+
<View style={styles.wrapper}>
|
|
260
|
+
<TabBar
|
|
261
|
+
tabs={tabs}
|
|
262
|
+
activeIndex={activeIndex}
|
|
263
|
+
onChange={onChange}
|
|
264
|
+
activeColor={theme.title}
|
|
265
|
+
inactiveColor="rgba(255,255,255,0.45)"
|
|
266
|
+
indicatorColor="#F7C977"
|
|
267
|
+
indicatorHeight={3}
|
|
268
|
+
fontSize={16}
|
|
269
|
+
fontWeightActive="700"
|
|
270
|
+
fontWeightInactive="500"
|
|
271
|
+
tabHorizontalPadding={8}
|
|
272
|
+
gap={20}
|
|
273
|
+
/>
|
|
274
|
+
</View>
|
|
275
|
+
<View style={styles.divider} />
|
|
276
|
+
</View>
|
|
277
|
+
);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
export const HoroscopeDailyOverview: Story = () => {
|
|
281
|
+
const [activeTab, setActiveTab] = useState(1);
|
|
282
|
+
|
|
283
|
+
return (
|
|
284
|
+
<ScreenSurface>
|
|
285
|
+
<HeaderHome
|
|
286
|
+
logo={<Text style={{ paddingHorizontal: SIZES.xs, fontSize: 24, fontWeight: '700', letterSpacing: 1, color: 'white' }}>CityLife</Text>}
|
|
287
|
+
onPress={() => console.log('filters')}
|
|
288
|
+
/>
|
|
289
|
+
<HoroscopeTabBar activeIndex={activeTab} onChange={setActiveTab} />
|
|
290
|
+
<ScrollView
|
|
291
|
+
showsVerticalScrollIndicator={false}
|
|
292
|
+
contentContainerStyle={{ gap: 24, paddingBottom: 32 }}
|
|
293
|
+
>
|
|
294
|
+
<HoroscopeDescription />
|
|
295
|
+
<HoroscopeCardsCarousel />
|
|
296
|
+
</ScrollView>
|
|
297
|
+
</ScreenSurface>
|
|
298
|
+
);
|
|
299
|
+
};
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rn-vs-lb",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.67",
|
|
4
4
|
"description": "Expo Router + Storybook template ready for npm distribution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"expo",
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
"@types/react": "~19.1.10",
|
|
80
80
|
"babel-plugin-react-docgen-typescript": "^1.5.1",
|
|
81
81
|
"cross-env": "^10.0.0",
|
|
82
|
+
"react-icons": "^5.5.0",
|
|
82
83
|
"storybook": "^9.1.8",
|
|
83
84
|
"typescript": "~5.9.2",
|
|
84
85
|
"vite": "^7.1.7"
|