Компоненты/QR-код

QR-код

31 января 2025

QR-код разворачивается по нажатию с плавным переходом

Установка

npx astra-rn add qr-code
pnpm dlx astra-rn add qr-code
yarn dlx astra-rn add qr-code
bunx --bun astra-rn add qr-code

Файлы

index.tsx
НазадПульсирующие точкиДалееРадарный луч

Вручную

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

npm install @expo/vector-icons react-native-qrcode-styled react-native-reanimated
pnpm add @expo/vector-icons react-native-qrcode-styled react-native-reanimated
yarn add @expo/vector-icons react-native-qrcode-styled react-native-reanimated
bun add @expo/vector-icons react-native-qrcode-styled react-native-reanimated

Скопируйте эти файлы в src/shared/components/base/qr-code/:

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

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

import { QRCode } from "@/shared/components/base/qr-code";
import { useQRCode } from "@/shared/components/base/qr-code/context";
import React from "react";
import { StyleSheet, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Showcase, useAutoplay, useCustomize } from "~/showcase";

const CUSTOMIZE = [
  { key: "label", label: "Текст кнопки", type: "text", default: "Show QR Code", maxLength: 24 },
  { key: "value", label: "Содержимое QR", type: "text", default: "#", maxLength: 200 },
  { key: "copyLabel", label: "Текст «Копировать»", type: "text", default: "Copy", maxLength: 16 },
  { key: "size", label: "Размер QR", type: "slider", min: 120, max: 260, step: 2, unit: "px", default: 190 },
  { key: "focusedColor", label: "Фон раскрытого", type: "color", default: "#eeedf4" },
] as const;

function QRCodeAutoplay() {
  const { expand, collapse, pressIn, pressOut, progress } = useQRCode();

  useAutoplay(
    async ({ wait }) => {
      await wait(330);
      if (progress.value < 0.5) {
        pressIn?.();
        try {
          await wait(120);
        } finally {
          pressOut?.();
        }
      }
      expand();
      await wait(1550);
      collapse();
      await wait(750);
    },
  );

  return null;
}

export default function QrCodeScreen() {
  const custom = useCustomize(CUSTOMIZE);
  const insets = useSafeAreaInsets();
  return (
    <Showcase>
      <View
        style={[
          styles.stage,
          {
            paddingTop: insets.top,
          },
        ]}
      >
        <View style={[styles.qr, {}]}>
          <QRCode backgroundColorFocused={custom.focusedColor}>
            <QRCode.Label>{custom.label}</QRCode.Label>
            <QRCode.Value value={custom.value} size={custom.size} />
            <QRCode.Actions>
              <QRCode.ExpandableLabel
                onPress={(value) => console.log("copy", value)}
              >
                <QRCode.ExpandableLabel.Icon name="copy" />
                {custom.copyLabel}
              </QRCode.ExpandableLabel>
              <QRCode.CloseButton />
            </QRCode.Actions>
            <QRCodeAutoplay />
          </QRCode>
        </View>
      </View>
    </Showcase>
  );
}

const styles = StyleSheet.create({
  stage: {
    flex: 1,
    paddingBottom: 120,
  },
  container: { flex: 1, backgroundColor: "#000" },
  content: { padding: 16, gap: 16 },
  title: { color: "#fff", fontSize: 22, fontWeight: "600" },
  demo: { gap: 12 },
  qr: {
    justifyContent: "center",
    alignItems: "center",
    flex: 1,
  },
});

Пропсы

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

Тип WithSpringConfig

backgroundColorFocused?

Тип string

defaultExpanded?

Тип boolean

style?

Тип StyleProp<ViewStyle>

children

Тип React.ReactNode