Accordion 10.17.4
An accordion is a vertical stack of interactive headings used to toggle the display of further information; each item can be 'collapsed' with just a short label visible or 'expanded' to show the full content.
Based on Radix UI.
Anatomy
<Accordion> <Accordion.Item> <Accordion.Header> <Accordion.Button>...</Accordion.Button> </Accordion.Header> <Accordion.Content>...</Accordion.Content> </Accordion.Item> </Accordion>
Default
<Accordion />
component has two simple states: expand
and collapse
. On expand you can reveal additional hidden information.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
export const Default = () => (
<Accordion>
<Accordion.Item
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Default</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
<Accordion.Item
value="item-2"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Test accordion</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
export default Default;
Open by default
By adding a defaultValue
attribute to <Accordion />
, you can set the expanded
state by default.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
export const OpenByDefault = () => (
<Accordion defaultValue="item-1">
<Accordion.Item
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Test accordion</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
export default OpenByDefault;
Single open
Using the singleOpen
prop on <Accordion />
ensures that only one <Accordion.Item />
can be open at a time.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
export const SingleOpen = () => (
<Accordion singleOpen>
<Accordion.Item
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Test accordion</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
<Accordion.Item
value="item-2"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Test accordion</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
export default SingleOpen;
Disabled
When an <Accordion.Item />
is set to disabled
, it becomes impossible to change its state.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
export const Disabled = () => (
<Accordion>
<Accordion.Item
disabled
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180" disabled>
<Accordion.Button>
<span>Test accordion</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
export default Disabled;
Header content
Customize <Accordion.Header />
to meet your product's needs - you can add any content to <Accordion.Button />
for enhancements.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import {
ChatChat,
ChatComment,
ChatCommentAdd,
ChatDoubleBubble,
ControlsChevronDownSmall,
} from "@heathmont/moon-icons-tw";
export const HeaderContent = () => (
<Accordion>
<Accordion.Item
value="item-3"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header>
<Accordion.Button className="moon-open:[&_span_svg]:rotate-180">
<span className="grow">Test accordion</span>
<div className="flex text-moon-24 text-trunks items-center">
<ChatChat />
<ChatComment />
<ChatCommentAdd />
<ChatDoubleBubble />
</div>
<span className="flex justify-center w-6">
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</span>
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
export default HeaderContent;
Sizes
<Accordion />
component supports various sizes by using the itemSize
prop. If not specified, the default size is Medium (md
).
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
export const Sizes = () => (
<>
<Accordion itemSize="xl">
<Accordion.Item
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>X Large (xl)</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
<Accordion itemSize="lg">
<Accordion.Item
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Large (lg)</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
<Accordion>
<Accordion.Item
value="item-2"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Medium is default (md)</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
<Accordion itemSize="sm">
<Accordion.Item
value="item-3"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Small (sm)</span>
<ControlsChevronDownSmall className="text-trunks text-moon-16 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
</>
);
export default Sizes;
Customization
In case you need to add some extra styling to the <Accordion />
component, you can easily use the className
property. It applies not only to the <Accordion />
component itself but also to all its sub-components - <Accordion.Item />
, <Accordion.Header />
, <Accordion.Content />
, and <Accordion.Button />
.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
export const Customization = () => (
<>
<Accordion>
<Accordion.Item value="item-1">
<Accordion.Header className="moon-open:[&_svg]:rotate-180 bg-beerus">
<Accordion.Button>
<span>Test accordion with background</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content className="bg-beerus">
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
</>
);
export default Customization;
Open/Close all items programmatically
You can also control the state of the <Accordion.Item />
sub-components from outside the <Accordion /
> component itself.
"use client";
import Accordion from "@heathmont/moon-core-tw/lib/es/accordion/Accordion";
import Button from "@heathmont/moon-core-tw/lib/es/button/Button";
import { ControlsChevronDownSmall } from "@heathmont/moon-icons-tw";
import { useState } from "react";
export const ControlOutside = () => {
const items = ["item-1", "item-2"];
const [values, setValues] = useState(["item-1"]);
const toggleAll = () =>
values.length === 0 ? setValues(items) : setValues([]);
return (
<div className="flex flex-col gap-4 w-full">
<Button className="w-32" onClick={toggleAll}>
Toggle All
</Button>
<Accordion value={values} onValueChange={setValues}>
<Accordion.Item
value="item-1"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Default</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
<Accordion.Item
value="item-2"
className="border border-beerus rounded-moon-s-sm"
>
<Accordion.Header className="moon-open:[&_svg]:rotate-180">
<Accordion.Button>
<span>Test accordion</span>
<ControlsChevronDownSmall className="text-trunks text-moon-24 transition duration-200 moon-open:text-bulma" />
</Accordion.Button>
</Accordion.Header>
<Accordion.Content>
{/* cSpell:disable */}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur.
{/* cSpell:enable */}
</Accordion.Content>
</Accordion.Item>
</Accordion>
</div>
);
};
export default ControlOutside;
Accordion
These are props specific to the Accordion component:
Name | Type | Default |
---|---|---|
itemSize | "sm" | "md" | "lg" | "xl" | md |
singleOpen | boolean | false |
defaultValue | string | - |
value | "string[]" | - |
onValueChange | (value: string[]) => void | - |
className | string | - |
Accordion.Item
These are props specific to the Accordion.Item component:
Name | Type | Default |
---|---|---|
value* | string | - |
disabled | boolean | false |
className | string | - |
Properties indicated with * are required.
Accordion.Header
These are props specific to the Accordion.Header component:
Name | Type | Default |
---|---|---|
className | string | - |
Accordion.Content
These are props specific to the Accordion.Content component:
Name | Type | Default |
---|---|---|
className | string | - |
Accordion.Button
These are props specific to the Accordion.Button component:
Name | Type | Default |
---|---|---|
className | string | - |