Accordion
Expandable content sections with animated height transitions.
Yes. It uses accessibilityRole and accessibilityState.
Yes. It uses react-native-reanimated for smooth animations.
Yes. Use className to override any styles.
Web preview — components render natively on iOS & Android
import { Accordion, AccordionItem } from "@/components/ui/accordion";
export function MyScreen() {
return (
<Accordion defaultValue="item-1">
<AccordionItem value="item-1" trigger="Is it accessible?">
<Text>Yes. It uses accessibilityRole and accessibilityState.</Text>
</AccordionItem>
<AccordionItem value="item-2" trigger="Is it animated?">
<Text>Yes. It uses react-native-reanimated for smooth animations.</Text>
</AccordionItem>
<AccordionItem value="item-3" trigger="Can I customize it?">
<Text>Yes. Use className to override any styles.</Text>
</AccordionItem>
</Accordion>
);
}Installation#
npx @aniui/cli add accordionThis component requires react-native-reanimated for animations.
Usage#
app/index.tsx
import { Accordion, AccordionItem } from "@/components/ui/accordion";
export function MyScreen() {
return (
<Accordion defaultValue="item-1">
<AccordionItem value="item-1" trigger="Is it accessible?">
<Text>Yes. It uses accessibilityRole and accessibilityState.</Text>
</AccordionItem>
<AccordionItem value="item-2" trigger="Is it animated?">
<Text>Yes. It uses react-native-reanimated for smooth animations.</Text>
</AccordionItem>
<AccordionItem value="item-3" trigger="Can I customize it?">
<Text>Yes. Use className to override any styles.</Text>
</AccordionItem>
</Accordion>
);
}Compound Components#
ComponentDescription
AccordionRoot container that manages expanded state
AccordionItemIndividual collapsible section with trigger text
Props#
Accordion#
PropTypeDefault
defaultValuestring—type"single" | "multiple""single"classNamestring—AccordionItem#
PropTypeDefault
valuestringrequiredtriggerstringrequiredclassNamestring—Accessibility#
- Uses
@rn-primitives/accordionfor keyboard navigation and ARIA compliance. - Supports single and multiple open modes.
- Each trigger has
accessibilityRole="button"withaccessibilityStatefor expanded/collapsed.
Source#
components/ui/accordion.tsx
import React from "react";
import { View, Pressable, Text } from "react-native";
import * as AccordionPrimitive from "@rn-primitives/accordion";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
import { cn } from "@/lib/utils";
export interface AccordionProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
defaultValue?: string;
children?: React.ReactNode;
type?: "single" | "multiple";
}
export function Accordion({ className, defaultValue, children, type = "single", ...props }: AccordionProps) {
return (
<AccordionPrimitive.Root
type={type}
defaultValue={type === "single" ? defaultValue : defaultValue ? [defaultValue] : undefined}
asChild
>
<View className={cn("", className)} {...props}>{children}</View>
</AccordionPrimitive.Root>
);
}
export interface AccordionItemProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
value: string;
trigger: string;
children?: React.ReactNode;
}
export function AccordionItem({ value, trigger, className, children, ...props }: AccordionItemProps) {
return (
<AccordionPrimitive.Item value={value} asChild>
<View className={cn("border-b border-border", className)} {...props}>
<AccordionPrimitive.Trigger asChild>
<Pressable className="flex-row items-center justify-between px-4 py-4 min-h-12" accessible={true} accessibilityRole="button">
<Text className="text-base font-medium text-foreground flex-1">{trigger}</Text>
<Text className="text-muted-foreground text-lg">+</Text>
</Pressable>
</AccordionPrimitive.Trigger>
<AccordionPrimitive.Content>
<Animated.View entering={FadeIn.duration(200)} exiting={FadeOut.duration(150)}>
<View className="px-4 pb-4">{children}</View>
</Animated.View>
</AccordionPrimitive.Content>
</View>
</AccordionPrimitive.Item>
);
}