Компоненты/Частые вопросы

Частые вопросы

28 сентября 2026

Блок вопросов и ответов с плавно раскрывающимися панелями и поворачивающимся плюсом.

Установка

npx astra-rn add faq-section
pnpm dlx astra-rn add faq-section
yarn dlx astra-rn add faq-section
bunx --bun astra-rn add faq-section

Файлы

index.tsx
НазадВеерное менюДалееСтопка карточек

Секция с заголовком и списком вопросов. По нажатию ответ раскрывается пружинной анимацией высоты, текст проявляется с небольшим сдвигом, а плюс поворачивается в крестик и заливается цветом. Карточки появляются по очереди при первом показе.

Можно разрешить несколько открытых ответов одновременно или разложить вопросы в две колонки. Высота ответа измеряется один раз, а анимация идёт на UI-потоке Reanimated; при «Уменьшении движения» остаются только переходы прозрачности. Работает на iOS, Android и в вебе.

Вручную

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

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

Скопируйте эти файлы в src/shared/components/organisms/faq-section/:

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

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

import React from "react";
import { ScrollView, StyleSheet, View } from "react-native";
import { FaqSection } from "@/shared/components/organisms/faq-section";
import { Showcase, useCustomize } from "~/showcase";

const CUSTOMIZE = [
  { key: "gap", label: "Отступ между вопросами", type: "slider", min: 0, max: 32, step: 1, unit: "px", default: 12 },
  { key: "radius", label: "Скругление карточек", type: "slider", min: 0, max: 32, step: 1, unit: "px", default: 16 },
  { key: "title", label: "Заголовок", type: "text", default: "Частые вопросы", maxLength: 40 },
  { key: "subtitle", label: "Подзаголовок", type: "text", default: "Всё, что стоит знать, прежде чем начать работу.", maxLength: 80 },
  {
    key: "align",
    label: "Выравнивание заголовка",
    type: "select",
    options: [
      { value: "center", label: "По центру" },
      { value: "left", label: "Слева" },
    ],
    default: "center",
  },
  {
    key: "columns",
    label: "Колонки",
    type: "select",
    options: [
      { value: "1", label: "Одна" },
      { value: "2", label: "Две" },
    ],
    default: "1",
  },
  { key: "allowMultiple", label: "Несколько открытых сразу", type: "toggle", default: false },
  { key: "accent", label: "Цвет открытого плюса", type: "color", default: "#f4f4f5" },
] as const;

export default function FaqSectionScreen() {
  const custom = useCustomize(CUSTOMIZE);

  return (
    <Showcase>
      <ScrollView style={styles.scroll} contentContainerStyle={styles.container}>
        <View style={styles.stage}>
          <FaqSection
            defaultOpenId="what-is-it"
            gap={custom.gap}
            radius={custom.radius}
            title={custom.title}
            subtitle={custom.subtitle}
            align={custom.align === "left" ? "left" : "center"}
            columns={custom.columns === "2" ? 2 : 1}
            allowMultiple={custom.allowMultiple}
            accentColor={custom.accent.toLowerCase() === "#f4f4f5" ? undefined : custom.accent}
          />
        </View>
      </ScrollView>
    </Showcase>
  );
}

const styles = StyleSheet.create({
  scroll: {
    flex: 1,
    backgroundColor: "#0a0a0a",
  },
  container: {
    flexGrow: 1,
    alignItems: "center",
    justifyContent: "center",
    paddingTop: 56,
    paddingBottom: 24,
  },
  stage: {
    width: "100%",
    alignItems: "center",
    justifyContent: "center",
    paddingHorizontal: 16,
    paddingVertical: 48,
  },
});

Пропсы

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

Тип readonly FaqItem[]

title?

Тип string

subtitle?

Тип string

defaultOpenId?

Тип string | null

allowMultiple?

Тип boolean

align?

Тип "center" | "left"

columns?

Тип 1 | 2

gap?

Тип number

radius?

Тип number

accentColor?

Тип string

theme?

Тип "dark" | "light"

style?

Тип StyleProp<ViewStyle>