Accordion
tetra-ui/accordionFreeComponent
A vertically stacked set of interactive headings that reveal associated content sections.
Live preview
live · rendered by the registry
Rendered by tetra-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://tetra-ui.com/r/accordion.jsonSource
1import type { ComponentPropsWithRef, ComponentRef, ReactNode } from "react";2import {3 Children,4 createContext,5 isValidElement,6 useCallback,7 useContext,8 useEffect,9 useId,10 useMemo,11 useRef,12 useState,13} from "react";14import {15 type GestureResponderEvent,16 Pressable,17 View,18 type ViewProps,19} from "react-native";20import Animated, {21 FadeInDown,22 FadeOutUp,23 LinearTransition,24 useAnimatedStyle,25 useSharedValue,26 withSpring,27} from "react-native-reanimated";28import { cn, mergeRefs } from "@/lib/utils";29import { ChevronDownIcon } from "./icons";30import { Slot } from "./slot";3132// Constants33const CONTENT_ENTER = FadeInDown.springify()34 .damping(28)35 .stiffness(340)36 .mass(0.55);37const CONTENT_EXIT = FadeOutUp.duration(120).damping(32).stiffness(380);38const ITEM_LAYOUT = LinearTransition.springify()39 .damping(28)40 .stiffness(340)41 .mass(0.6);42const ICON_SPRING = { damping: 26, mass: 0.5, stiffness: 320 };4344// Types45type AccordionType = "single" | "multiple";4647type AccordionItemLayout =48 | "open"49 | "closed-only"50 | "closed-start"51 | "closed-middle"52 | "closed-end";5354const ACCORDION_ITEM_LAYOUT_CLASSNAME = {55 "closed-end": "my-0 rounded-b-2xl",56 "closed-middle": "my-0 rounded-none",57 "closed-only": "my-0 rounded-2xl",58 "closed-start": "my-0 rounded-t-2xl",59 open: "my-2 rounded-2xl",60} as const satisfies Record<AccordionItemLayout, string>;6162const AnimatedView = Animated.createAnimatedComponent(View);6364type AccordionRootContextValue = {65 type: AccordionType;66 collapsible: boolean;67 itemLayouts: Record<string, AccordionItemLayout>;68 /** single: one value; multiple: open value set */69 isOpen: (value: string) => boolean;70 toggle: (value: string) => void;71};7273type AccordionItemContextValue = {74 value: string;75 isOpen: boolean;76 contentId: string;77 triggerId: string;78};7980const AccordionRootContext = createContext<AccordionRootContextValue | null>(81 null82);83const AccordionItemContext = createContext<AccordionItemContextValue | null>(84 null85);8687const useAccordionRoot = () => {88 const ctx = useContext(AccordionRootContext);89 if (!ctx) {90 throw new Error("Accordion components must be used within Accordion");91 }92 return ctx;93};9495const useAccordionItem = () => {96 const ctx = useContext(AccordionItemContext);97 if (!ctx) {98 throw new Error(99 "AccordionItem, AccordionTrigger, AccordionContent, and AccordionIndicator must be used within AccordionItem"100 );101 }102 return ctx;103};104105// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from tetra-ui
All 41 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Inputaction-input | tetra-ui | Components | Free | no deps | |
| Alertalert | tetra-ui | Components | Free | no deps | |
| Avataravatar | tetra-ui | Components | Free | no deps | |
| Badgebadge | tetra-ui | Components | Free | no deps | |
| Bottom Sheetbottom-sheet | tetra-ui | Components | Free | 4 deps · 7 files | |
| Buttonbutton | tetra-ui | Components | Free | no deps | |
| Cardcard | tetra-ui | Components | Free | no deps | |
| Checkboxcheckbox | tetra-ui | Components | Free | 1 dep |
