Accordion

The Accordion component is a versatile and interactive user interface element, designed to efficiently organize and present content in a compact space.
Installation
API Reference
Examples
This is an illustration of Accordion component.
size
variant
type
isCollapsible
isDisabled
<Accordion
m="$5"
width="90%"
size="md"
variant="filled"
type="single"
isCollapsible={true}
isDisabled={false}
>
<AccordionItem value="a">
<AccordionHeader>
<AccordionTrigger>
{({ isExpanded }) => {
return (
<>
<AccordionTitleText>How do I place an order?</AccordionTitleText>
{isExpanded ? (
<AccordionIcon as={ChevronUpIcon} ml="$3" />
) : (
<AccordionIcon as={ChevronDownIcon} ml="$3" />
)}
</>
)
}}
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<AccordionContentText>
To place an order, simply select the products you want, proceed to
checkout, provide shipping and payment information, and finalize your
purchase.
</AccordionContentText>
</AccordionContent>
</AccordionItem>
<AccordionItem value="b">
<AccordionHeader>
<AccordionTrigger>
{({ isExpanded }) => {
return (
<>
<AccordionTitleText>
What payment methods do you accept?
</AccordionTitleText>
{isExpanded ? (
<AccordionIcon as={ChevronUpIcon} ml="$3" />
) : (
<AccordionIcon as={ChevronDownIcon} ml="$3" />
)}
</>
)
}}
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<AccordionContentText>
We accept all major credit cards, including Visa, Mastercard, and
American Express. We also support payments through PayPal.
</AccordionContentText>
</AccordionContent>
</AccordionItem>
</Accordion>

Installation

Step 1: Install the following dependencies:

npm i @gluestack-ui/accordion

Step 2: Copy and paste the following code into your project.

"use client"
import { createAccordion } from "@gluestack-ui/accordion"
import { AsForwarder, styled } from "@gluestack-style/react"
import { View, Pressable, Text, Platform } from "react-native"
import { H3 } from "@expo/html-elements"
const StyleRoot = styled(
View,
{
width: "$full",
_icon: {
color: "$text900",
},
_titleText: {
color: "$text900",
},
_contentText: {
color: "$text700",
},
variants: {
size: {
sm: {
_titleText: {
fontSize: "$sm",
fontFamily: "$body",
fontWeight: "$bold",
lineHeight: "$sm",
},
_contentText: {
fontSize: "$sm",
fontFamily: "$body",
fontWeight: "$normal",
lineHeight: "$sm",
},
},
md: {
_titleText: {
fontSize: "$md",
fontFamily: "$body",
fontWeight: "$bold",
lineHeight: "$md",
},
_contentText: {
fontSize: "$md",
fontFamily: "$body",
fontWeight: "$normal",
lineHeight: "$md",
},
},
lg: {
_titleText: {
fontSize: "$lg",
fontFamily: "$body",
fontWeight: "$bold",
lineHeight: "$lg",
},
_contentText: {
fontSize: "$lg",
fontFamily: "$body",
fontWeight: "$normal",
lineHeight: "$lg",
},
},
},
variant: {
filled: {
backgroundColor: "$white",
_item: {
backgroundColor: "$background0",
},
shadowColor: "$background900",
shadowOffset: {
width: 0,
height: 3,
},
shadowRadius: 8,
shadowOpacity: 0.2,
elevation: 10,
},
unfilled: {
shadowColor: "transparent",
shadowOffset: {
width: 0,
height: 0,
},
_item: {
backgroundColor: "transparent",
},
},
},
},
defaultProps: {
theme: "light",
size: "md",
variant: "filled",
},
},
{
descendantStyle: [
"_item",
"_titleText",
"_button",
"_icon",
"_contentText",
],
}
)
const StyledItem = styled(View, {}, { ancestorStyle: ["_item"] })
// @ts-ignore
const StyledHeader = styled(Platform.OS === "web" ? H3 : View, {
mx: "$0",
my: "$0",
})
const StyledTrigger = styled(
Pressable,
{
width: "$full",
py: "$5",
px: "$5",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
_web: {
outlineWidth: 0,
},
":disabled": {
opacity: 0.4,
_web: {
cursor: "not-allowed",
},
},
":focusVisible": {
bg: "$background50",
},
},
{
descendantStyle: ["_icon", "_titleText", "_contentText"],
ancestorStyle: ["_button"],
}
)
const StyledText = styled(
Text,
{
color: "$text700",
flex: 1,
fontWeight: "$normal",
fontFamily: "$body",
fontStyle: "normal",
letterSpacing: "$md",
variants: {
isTruncated: {
true: {
props: {
// @ts-ignore
numberOfLines: 1,
ellipsizeMode: "tail",
},
},
},
bold: {
true: {
fontWeight: "$bold",
},
},
underline: {
true: {
textDecorationLine: "underline",
},
},
strikeThrough: {
true: {
textDecorationLine: "line-through",
},
},
size: {
"2xs": {
fontSize: "$2xs",
},
xs: {
fontSize: "$xs",
},
sm: {
fontSize: "$sm",
},
md: {
fontSize: "$md",
},
lg: {
fontSize: "$lg",
},
xl: {
fontSize: "$xl",
},
"2xl": {
fontSize: "$2xl",
},
"3xl": {
fontSize: "$3xl",
},
"4xl": {
fontSize: "$4xl",
},
"5xl": {
fontSize: "$5xl",
},
"6xl": {
fontSize: "$6xl",
},
},
sub: {
true: {
fontSize: "$xs",
},
},
italic: {
true: {
fontStyle: "italic",
},
},
highlight: {
true: {
bg: "$yellow500",
},
},
},
defaultProps: {
size: "md",
},
},
{
ancestorStyle: ["_text"],
}
)
const StyledTitleText = styled(
StyledText,
{ flex: 1, textAlign: "left" },
{ ancestorStyle: ["_titleText"] }
)
const StyledContentText = styled(Text, {}, { ancestorStyle: ["_contentText"] })
const StyledIcon = styled(
AsForwarder,
{
color: "$background800",
// defaultProps: {
// size: 'md',
// },
variants: {
size: {
"2xs": {
h: "$3",
w: "$3",
props: {
// @ts-ignore
size: 12,
},
},
xs: {
h: "$3.5",
w: "$3.5",
props: {
//@ts-ignore
size: 14,
},
},
sm: {
h: "$4",
w: "$4",
props: {
//@ts-ignore
size: 16,
},
},
md: {
h: "$4.5",
w: "$4.5",
props: {
//@ts-ignore
size: 18,
},
},
lg: {
h: "$5",
w: "$5",
props: {
//@ts-ignore
size: 20,
},
},
xl: {
h: "$6",
w: "$6",
props: {
//@ts-ignore
size: 24,
},
},
},
},
props: {
size: "md",
},
},
{
resolveProps: ["stroke", "fill"],
ancestorStyle: ["_icon"],
},
{
propertyTokenMap: {
stroke: "colors",
fill: "colors",
},
}
)
const StyledContent = styled(View, { px: "$5", mt: "$2", pb: "$5" })
export const Accordion = createAccordion({
Root: StyleRoot,
Item: StyledItem,
Header: StyledHeader,
Trigger: StyledTrigger,
Icon: StyledIcon,
TitleText: StyledTitleText,
ContentText: StyledContentText,
Content: StyledContent,
})
export const AccordionItem = Accordion.Item
export const AccordionHeader = Accordion.Header
export const AccordionTrigger = Accordion.Trigger
export const AccordionTitleText = Accordion.TitleText
export const AccordionContentText = Accordion.ContentText
export const AccordionIcon = Accordion.Icon
export const AccordionContent = Accordion.Content

Step 3: Update the import paths to match your project setup.

API Reference

To use this component in your project, include the following import statement in your file.
import {
Accordion,
AccordionItem,
AccordionHeader,
AccordionTrigger,
AccordionTitleText,
AccordionIcon,
AccordionContent,
AccordionContentText,
} from "@/components/ui/accordion"
export default () => (
<Accordion>
<AccordionItem>
<AccordionHeader>
<AccordionTrigger>
<AccordionTitleText />
<AccordionIcon />
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<AccordionContentText />
</AccordionContent>
</AccordionItem>
</Accordion>
)

Component Props

This section provides a comprehensive reference list for the component props, detailing descriptions, properties, types, and default behavior for easy project integration.

Accordion

It inherits all the properties of React Native's View component.
Prop
Type
Default
Description
type
"single" | "multiple"
"single"
Determines whether one or multiple items can be opened at the same time.
isCollapsible
boolean
true
When type is "single" or "multiple", allows closing content when clicking trigger for an open item.
defaultValue
string[]
[]
The value of the item to expand when initially rendered when type is "single" or "multiple".
value
string[]
[]
The controlled value of the item to expand when type is "single" or "multiple".
onValueChange
function
-
Event handler called when the expanded state of an item changes and type is "single" or "multiple".
isDisabled
boolean
false
When true, prevents the user from interacting with the accordion and all its items.
Descendants Styling Props Props to style child components.
Sx Prop
Description
_item
Prop to style the AccordionItem Component
_titleText
Prop to style the AccordionTitleText Component
_contentText
Prop to style the AccordionContentText Component
_icon
Prop to style the AccordionIcon Component

AccordionItem

Contains all the parts of a collapsible section.
Prop
Type
Default
Description
value
string
-
The controlled value of the item to expand when type is "single" or "multiple". Must be used in conjunction with onValueChange.This is a mandatory prop.
isDisabled
boolean
false
When true, prevents the user from interacting with the accordion and all its items.

AccordionHeader

Wraps an Accordion.Trigger. It inherits all the properties of @expo/html-elements's H3 on web and It inherits all the properties of react native's View on native. Use the as prop to update it to the appropriate heading level for your page.

AccordionTrigger

Toggles the collapsed state of its associated item. It inherits all the properties of react native's Pressable. It should be nested inside of an Accordion.Header.

AccordionTitleText

It inherits all the properties of React Native's Text component.

AccordionIcon

Contains all Icon related layout style props and actions.It inherits all the properties of React Native's View component.

AccordionContent

Contains all the collapsible content for an item. It inherits all the properties of React Native View component.

AccordionContentText

It inherits all the properties of React Native's Text component.

Accessibility

Adheres to the Accordion WAI-ARIA design pattern.
We have outlined the various features that ensure the Accordion component is accessible to all users, including those with disabilities. These features help ensure that your application is inclusive and meets accessibility standards.
  • Header is h3 tag on web.
  • aria-expanded is "true" when the Accordion Content is visible, otherwise false.
  • role is set to "region" for the currently expanded accordion panel.
  • aria-controls points to the id of the Accordion Content.
  • aria-labelledby references the accordion header button that expands and collapses the region.

Keyboard Interactions

  • Space - When focus is on an Accordion.Trigger of a collapsed section, expands the section.
  • Enter - When focus is on an Accordion.Trigger of a collapsed section, expands the section.
  • Tab - Moves focus to the next focusable element.
  • Shift + Tab - Moves focus to the previous focusable element.

Screen Reader