Компоненты/Тягучий переключатель

Тягучий переключатель

1 февраля 2025

Переключатель на текучих каплях

Установка

npx astra-rn add gooey-switch
pnpm dlx astra-rn add gooey-switch
yarn dlx astra-rn add gooey-switch
bunx --bun astra-rn add gooey-switch

Файлы

index.tsx
НазадТягучий статус-бейджДалееКарточки с градиентом

Вручную

Поставьте зависимости:

npm install @expo/vector-icons @shopify/react-native-skia expo-symbols react-native-gesture-handler react-native-reanimated react-native-worklets
pnpm add @expo/vector-icons @shopify/react-native-skia expo-symbols react-native-gesture-handler react-native-reanimated react-native-worklets
yarn add @expo/vector-icons @shopify/react-native-skia expo-symbols react-native-gesture-handler react-native-reanimated react-native-worklets
bun add @expo/vector-icons @shopify/react-native-skia expo-symbols react-native-gesture-handler react-native-reanimated react-native-worklets

Скопируйте эти файлы в src/shared/components/micro-interactions/gooey-switch/:

Проверьте алиас путей. Импорты в коде выше записаны так, как их пишет astra-rn add: @/shared/components, @/shared/utils и @/shared/hooks. Нужен алиас "@/*": ["./src/*"] в tsconfig.json — или поправьте импорты под свои пути.

Использование

import { useState } from "react";
import { View, StyleSheet } from "react-native";
import { StatusBar } from "expo-status-bar";
import GooeySwitch from "@/shared/components/micro-interactions/gooey-switch";
import { Showcase, useAutoplay, useCustomize } from "~/showcase";

const CUSTOMIZE = [
  { key: "activeColor", label: "Цвет «вкл»", type: "color", default: "#e8861e" },
  { key: "inactiveColor", label: "Цвет «выкл»", type: "color", default: "#9ca3af" },
  { key: "trackColor", label: "Цвет дорожки", type: "color", default: "#1a1a1a" },
  { key: "iconTint", label: "Цвет иконок", type: "color", default: "#ffffff" },
  { key: "size", label: "Размер", type: "slider", min: 80, max: 300, step: 5, unit: "px", default: 200 },
  { key: "gooey", label: "Липкость", type: "slider", min: 0, max: 80, step: 1, default: 35 },
  { key: "squishY", label: "Сжатие", type: "slider", min: 0.2, max: 1.2, step: 0.05, default: 0.5 },
  { key: "stretchX", label: "Растяжение", type: "slider", min: 0.8, max: 2, step: 0.05, default: 1.2 },
  { key: "showIcons", label: "Иконки", type: "toggle", default: true },
] as const;

export default function App() {
  const [active, setActive] = useState<boolean>(false);
  const custom = useCustomize(CUSTOMIZE);

  useAutoplay(async ({ wait }) => {
    await wait(150);
    setActive(true);
    await wait(800);
    setActive(false);
    await wait(450);
  });

  return (
    <Showcase>
      <View style={styles.container}>
        <StatusBar style="light" />

        <View style={styles.content}>
          <GooeySwitch
            active={active}
            onToggle={setActive}
            activeColor={custom.activeColor}
            inactiveColor={custom.inactiveColor}
            iconTint={custom.iconTint}
            showIcons={custom.showIcons}
            size={custom.size}
            trackColor={custom.trackColor}
            gooey={custom.gooey}
            deformation={{
              squishY: custom.squishY,
              stretchX: custom.stretchX,
            }}
          />
        </View>
      </View>
    </Showcase>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#0a0a0a",
  },
  content: {
    alignItems: "center",
    justifyContent: "center",
    flex: 1,
  },
});

Пропсы

Пропс
Описание
active?

Тип boolean

onToggle?

Тип (active: boolean) => void

size?

Тип number

inactiveColor?

Тип string

activeColor?

Тип string

trackColor?

Тип string

iconTint?

Тип string

toggleThreshold?

Тип number

isDisabled?

Тип boolean

showIcons?

Тип boolean

animation?

Тип WithSpringConfig

deformation?

Тип IBlobConfig

connector?

Тип BridgeConfig

blur?

Тип number

gooey?

Тип number

renderActiveIcon?

Тип (props: IconRender) => React.ReactNode

renderInactiveIcon?

Тип (props: IconRender) => React.ReactNode

onDragBegin?

Тип () => void

onDragFinish?

Тип (active: boolean) => void

IBlobConfig

Пропс
Описание
stretchX?

Тип number

squishY?

Тип number

sideBlobScale?

Тип number