Components · Data display
Accordion
BetaShows and hides sections, such as FAQ entries.
- Source
components/ui/accordion.tsx - shadcn/ui Accordion
- Figma: not linked yet (Q13)
When to use
- For a list of questions and answers that people scan for the one they need: the FAQ in the client app, a coach's package page.
- For long, repeated sections where the coach works on one or two at a time: the weeks of a program, the days of a nutrition plan.
When not to use
- For a single section: use a Collapsible.
- When people need to compare sections side by side, or read all of them: show them on the page with headings.
- To switch between views of the same thing: use Tabs.
- For short content that fits on the page anyway. Hiding it only adds clicks.
Anatomy
- 1. Trigger: a button inside a heading, with a chevron at the end that turns when open
- 2. Content: the open item's answer
- 3. Item: a closed item; items are divided by a border
Variants
- Upper body A, 3 × 10
- Lower body A, 3 × 10
- Conditioning, 20 min
- Upper body A, 4 × 10
- Lower body A, 4 × 10
- Conditioning, 25 min
| Variant | Use for |
|---|---|
Single (type="single" collapsible) | FAQs and settings: opening one item closes the other. Add collapsible so the open item can be closed too. |
Multiple (type="multiple") | Program weeks, plan days: the coach may want several open to compare. |
Set the items open at first with defaultValue (a string for single, an array for multiple). Open the first item when most people need it; otherwise start with everything closed.
States
| State | What changes | Token |
|---|---|---|
| Closed | Content hidden; chevron points down | text-muted-foreground (chevron) |
| Open | Content shows; chevron turns 180° | duration-(--duration-base) |
| Hover | Trigger text underlines | hover:underline |
| Focus-visible | Ring around the trigger | ring-ring/50, 3px |
| Disabled | Half opacity, can't be opened | opacity-(--opacity-disabled) |
The content opens and closes with a height animation (animate-accordion-down, animate-accordion-up) from tw-animate-css. It runs for --duration-base, and with reduced motion turned on, sections open and close without the animation.
Usage guidelines
- Write each trigger so the coach can tell, without opening it, whether the answer is there.
- Keep the order meaningful: most asked first in an FAQ, chronological for weeks.
- Don't nest accordions. If a section needs its own sections, it wants a page.
- Don't put the only Save button of a form inside an item that can be closed.
Content guidelines
- FAQ triggers are the question, as the client would ask it, with a question mark: "How do I log a workout?".
- Section triggers are short nouns: "Week 3: Deload". Sentence case.
- Answers start with the answer ("Yes.", "Open Today…"), then the detail. Two or three sentences.
- Arabic questions are written as a client would ask them: "كيف أسجّل تمرينًا؟", with the Arabic question mark.
Accessibility
| Key | Does |
|---|---|
| Tab | Moves to the next trigger, or into the open content |
| Enter / Space | Opens or closes the focused item |
| Arrow down / up | Moves to the next / previous trigger, wrapping at the ends |
| Home / End | First / last trigger |
- Each trigger is a
buttoninside a heading (h3by default), witharia-expandedandaria-controls. Announced as "How do I log a workout?, button, expanded, heading level 3". - Open content is a
regionlabelled by its trigger, so screen reader users can jump back to the question. - Arrow keys move between triggers only; Tab still moves through everything, including links inside the content.
- The heading level is fixed at
h3by shadcn'sAccordionTrigger. Check that it fits the page's outline (QUESTIONS Q6 lists a heading-level prop as a possible change).
RTL
Triggers and content follow the reading order, and the chevron sits at the end (left in RTL). The chevron points down and turns up, so it doesn't mirror. Up and down arrows don't change with the direction. A question that wraps onto two lines aligns to the start (text-start; upstream used text-left, which aligned it left in RTL).
Tokens used
Read from components/ui/accordion.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.
| Token | Utilities | SuperCoach | Coach |
|---|---|---|---|
| --muted-foreground | text-muted-foreground | neutral-600 | neutral-600 |
| --ring | border-ring ring-ring/50 | brand-600 | orange-500 |
- Motion
duration-(--duration-base) - Opacity
opacity-(--opacity-disabled) - Radius
rounded-md - Type
font-medium - Type
text-sm
Props
<Accordion>
Also takes every prop of Radix Accordion.Root
No props of its own.
<AccordionItem>
Also takes every prop of Radix Accordion.Item
No props of its own.
<AccordionTrigger>
Also takes every prop of Radix Accordion.Trigger
No props of its own.
<AccordionContent>
Also takes every prop of Radix Accordion.Content
No props of its own.
type, collapsible, value, defaultValue, onValueChange and disabled come from Radix Accordion.
Replaces in coach-admin
From the read-only audit of coach-admin: 129 style values, 152 uses.
coach-admin has at least three accordions: custom-accordion (with a surface variant), the form accordion in formComponents/accordion, and the follow-up tasks' schedule-accordion, plus Bootstrap's .accordion-button and the landing page FAQ. All become Accordion.
Classes and selectors
.schedule-accordion12.customAccordionBody8.customAccordionHeader7.custom-accordion--surface4.customAccordionContainer4.custom-accordion__content-inner4.accordion-button::after4.custom-accordion-container--surface3&.customAccordionBodyActive3.customAccordionExpandBtn3.custom-accordion2.custom-accordion__arrow2
Files
src/views/Pages/FollowUpTasksPage/Pages/TasksReview/schedule-accordion.scss52src/reusableComponents/custom-accordion/custom-accordion.module.scss44src/reusableComponents/formComponents/accordion/accordion.scss24src/views/LandingPage/components/FAQSection/FAQSection.scss6
The inventory lists the first 12 locations of each value, so file counts are a lower bound.
SCSS variables in these styles
$spacing-mdnot a color: spacing, size or layout$border-strong-color→--border-strong$spacing-2xsnot a color: spacing, size or layout$spacing-smnot a color: spacing, size or layout$scroll-thumb-color→ nearest neutral-300 (no semantic token)$timeline-line-color→ nearest neutral-100 (no semantic token)$spacing-xlnot a color: spacing, size or layout$spacing-xsnot a color: spacing, size or layout$scroll-thumb-hover-color→ nearest neutral-400 (no semantic token)$spacing-lgnot a color: spacing, size or layout$spacing-2xlnot a color: spacing, size or layout$primary-color→--primary
Related
Collapsible, Tabs, Card, Separator.