Поставьте зависимости:
npm install expo-blur expo-haptics react-native-gesture-handler react-native-reanimated react-native-workletspnpm add expo-blur expo-haptics react-native-gesture-handler react-native-reanimated react-native-workletsyarn add expo-blur expo-haptics react-native-gesture-handler react-native-reanimated react-native-workletsbun add expo-blur expo-haptics react-native-gesture-handler react-native-reanimated react-native-workletsСкопируйте эти файлы в src/shared/components/organisms/segmented-control/:
Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.
import { Dimensions, StyleSheet, Text, View } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar";
import { useState } from "react";
import SegmentedControl from "@/shared/components/organisms/segmented-control";
import { useFonts } from "expo-font";
import { Showcase, useAutoplay, useCustomize } from "~/showcase";
const CUSTOMIZE = [
{ key: "label1", label: "Вкладка 1", type: "text", default: "Home", maxLength: 16 },
{ key: "label2", label: "Вкладка 2", type: "text", default: "Favorites", maxLength: 16 },
{ key: "label3", label: "Вкладка 3", type: "text", default: "Profile", maxLength: 16 },
{
key: "preset",
label: "Тема",
type: "select",
options: [
{ value: "ios", label: "iOS" },
{ value: "light", label: "Светлая" },
{ value: "dark", label: "Тёмная" },
{ value: "ocean", label: "Океан" },
{ value: "sunset", label: "Закат" },
{ value: "forest", label: "Лес" },
{ value: "purple", label: "Фиолетовая" },
{ value: "rose", label: "Роза" },
],
default: "ios",
},
{ key: "textColor", label: "Цвет текста", type: "color", default: "#000000" },
{ key: "fontSize", label: "Размер текста", type: "slider", min: 10, max: 20, step: 1, unit: "px", default: 14 },
{ key: "paddingVertical", label: "Отступ", type: "slider", min: 2, max: 20, step: 0.5, unit: "px", default: 8.5 },
{ key: "borderRadius", label: "Скругление", type: "slider", min: 0, max: 200, step: 1, unit: "px", default: 200 },
{ key: "scaleEffect", label: "Эффект нажатия", type: "toggle", default: true },
] as const;
type TPreset = "ios" | "light" | "dark" | "ocean" | "sunset" | "forest" | "purple" | "rose";
const { width: _width } = Dimensions.get("window");
const TABS = [
{ icon: "home", label: "Home", color: "#000000" },
{ icon: "heart", label: "Favorites", color: "#000" },
{ icon: "user", label: "Profile", color: "#000000" },
] as const;
export default function App() {
const [fontLoaded] = useFonts({
SfProRounded: require("@/assets/fonts/sf-pro-rounded.ttf"),
HelveticaNowDisplay: require("@/assets/fonts/HelveticaNowDisplayMedium.ttf"),
});
const custom = useCustomize(CUSTOMIZE);
const labels = [custom.label1, custom.label2, custom.label3];
const [index, setIndex] = useState(0);
useAutoplay(async ({ wait }) => {
const steps: [number, number][] = [
[0, 700],
[1, 620],
[2, 620],
[1, 580],
[0, 580],
[1, 620],
[2, 1000],
[1, 900],
[0, 1100],
];
for (const [next, hold] of steps) {
setIndex(next);
await wait(hold);
}
});
return (
<Showcase>
<GestureHandlerRootView style={styles.container}>
<StatusBar style="light" />
<View style={styles.card}>
<SegmentedControl
currentIndex={index}
onChange={setIndex}
preset={custom.preset as TPreset}
paddingVertical={custom.paddingVertical}
borderRadius={custom.borderRadius}
width={_width - 120}
disableScaleEffect={!custom.scaleEffect}
>
{TABS.map((tab, tabIndex) => (
<View key={tab.label} style={styles.tab}>
<Text
style={[
styles.tabText,
{
color: custom.textColor,
fontSize: custom.fontSize,
fontFamily: fontLoaded ? "SfProRounded" : undefined,
},
]}
>
{labels[tabIndex]}
</Text>
</View>
))}
</SegmentedControl>
</View>
</GestureHandlerRootView>
</Showcase>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#0a0a0a",
alignItems: "center",
justifyContent: "center",
},
card: {},
tab: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 6,
},
tabText: {
textAlign: "center",
fontSize: 14,
fontWeight: "500",
color: "#000000",
},
content: {
marginTop: 24,
alignItems: "center",
},
title: {
fontSize: 20,
fontWeight: "600",
color: "#fff",
marginBottom: 6,
},
subtitle: {
fontSize: 13,
color: "rgba(255,255,255,0.6)",
textAlign: "center",
maxWidth: 260,
},
});childrenТип React.ReactNode
onChangeТип (index: number) => void
currentIndexТип number
preset?Тип SegmentedControlPreset
segmentedControlBackgroundColor?Тип string
activeSegmentBackgroundColor?Тип string
paddingVertical?Тип number
dividerColor?Тип string
borderRadius?Тип number
disableScaleEffect?Тип boolean
width?Total width of the control. Defaults to the screen width minus 32.
Тип number