Компоненты/Круговой лоадер

Круговой лоадер

31 января 2025

Круговой индикатор вращается, при желании — с градиентом

Установка

npx astra-rn add circular-loader
pnpm dlx astra-rn add circular-loader
yarn dlx astra-rn add circular-loader
bunx --bun astra-rn add circular-loader

Файлы

index.tsx
НазадКруговой списокДалееКруговой прогресс

Вручную

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

npm install react-native-svg
pnpm add react-native-svg
yarn add react-native-svg
bun add react-native-svg

Скопируйте эти файлы в src/shared/components/molecules/circular-loader/:

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

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

import { View, StyleSheet } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar";

import { CircularLoader } from "@/shared/components/molecules/circular-loader";
import { Showcase, useCustomize } from "~/showcase";

const CUSTOMIZE = [
  { key: "color", label: "Цвет дуги", type: "color", default: "#ffffff" },
  { key: "size", label: "Размер", type: "slider", min: 16, max: 160, step: 1, unit: "px", default: 72 },
  { key: "strokeWidth", label: "Толщина", type: "slider", min: 1, max: 16, step: 0.5, unit: "px", default: 6 },
  { key: "duration", label: "Оборот", type: "slider", min: 200, max: 4000, step: 50, unit: "ms", default: 1000 },
  { key: "gradientLength", label: "Длина хвоста", type: "slider", min: 5, max: 70, step: 1, unit: "%", default: 50 },
  { key: "blur", label: "Размытие", type: "toggle", default: true },
  { key: "background", label: "Фон", type: "color", default: "#0a0a0a" },
] as const;

export default function App() {
  const custom = useCustomize(CUSTOMIZE);
  return (
    <Showcase>
      <GestureHandlerRootView
        style={[styles.container, { backgroundColor: custom.background }]}
      >
        <StatusBar style="light" />

        <View style={styles.content}>
          <CircularLoader
            activeColor={custom.color}
            size={custom.size}
            strokeWidth={custom.strokeWidth}
            duration={custom.duration}
            gradientLength={custom.gradientLength}
            enableBlur={custom.blur}
          />
        </View>
      </GestureHandlerRootView>
    </Showcase>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#0a0a0a",
    justifyContent: "center",
    alignItems: "center",
  },
  content: {
    justifyContent: "center",
    alignItems: "center",
    gap: 0,
  },
  title: {
    fontSize: 28,
    fontWeight: "700",
    color: "#fff",
  },
  subtitle: {
    fontSize: 15,
    color: "#555",
  },
  card: {
    backgroundColor: "#141414",
    borderRadius: 16,
    overflow: "hidden",
    marginTop: 20,
  },
  triggerContent: {
    padding: 16,
  },
  triggerLeft: {
    flexDirection: "row",
    alignItems: "center",
    gap: 12,
  },
  triggerText: {
    fontSize: 16,
    fontWeight: "500",
    color: "#fff",
  },
  item: {
    flexDirection: "row",
    alignItems: "center",
    gap: 12,
    padding: 14,
    backgroundColor: "#1a1a1a",
    borderRadius: 12,
    marginBottom: 6,
  },
  itemText: {
    fontSize: 15,
    color: "#fff",
  },
  destructiveText: {
    color: "#ff453a",
  },
});

Пропсы

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

Тип number

strokeWidth?

Тип number

activeColor?

Тип string

inactiveColor?

@readonly @not-in-use

Тип string

duration?

Тип number

style?

Тип ViewStyle

gradientLength?

Тип number

fadeOpacity?

Тип number

blurAmount?

Тип number

enableBlur?

Тип boolean