Accordion
콘텐츠의 숨겨진 내용을 확장하거나 축소하여 보여주는 요소입니다. 클릭하여 원하는 정보만 선택적으로 볼 수 있어, 제한된 공간에서 많은 정보를 효율적으로 구성하고 탐색할 수 있도록 돕습니다.
내용을 최소화하거나 펼칠 때 사용합니다.
import { Accordion, AccordionSummary, AccordionDetails, AccordionDescription } from '@montage-ui/core';
const Demo = () => {
return (
<Accordion sx={{ width: '100%' }}>
<AccordionSummary>
제목
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
)
}
export default Demo;아래와 같은 구조로 조합하여 사용합니다.
leadingContent를 추가하거나 기본 trailingContent를 교체할 수 있습니다.
trailingContent가 a 태그이거나 클릭 이벤트가 있는 경우 e.stopPropagation 을 통해 아코디언이 열리고 닫히는 동작을 막을 수 있습니다.
AccordionSummaryContent 컴포넌트로 감싸서 사용하고, rotate 옵션을 통해 열리고 닫힐 때 회전 여부를 결정할 수 있습니다.
import { Accordion, AccordionSummary, AccordionDetails, AccordionDescription, AccordionSummaryContent, IconButton, FlexBox } from '@montage-ui/core';
import { IconCircleCheckFill, IconChevronDown, IconArrowRight, IconCaretDown, IconPlus } from '@montage-ui/icon';
import { useState } from 'react';
const Demo = () => {
const [expandedCheckAccordion, setExpandedCheckAccordion] = useState(false);
return (
<FlexBox flexDirection="column" gap="12px" sx={{ width: '100%' }}>
<Accordion disabled>
<AccordionSummary>
Disabled, true
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
leadingContent={
<AccordionSummaryContent variant="icon">
<IconPlus />
</AccordionSummaryContent>
}
>
LeadingContent, Icon<br />
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
trailingContent={
<AccordionSummaryContent variant="icon" rotate>
<IconCaretDown />
</AccordionSummaryContent>
}
>
TrailingContent, Icon, Rotate<br />
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion
expanded={expandedCheckAccordion}
onChange={setExpandedCheckAccordion}
>
<AccordionSummary
trailingContent={
<AccordionSummaryContent
variant="icon"
>
<IconCircleCheckFill
sx={(theme) => ({
color: expandedCheckAccordion
? theme.semantic.foreground.brand.primary
: theme.semantic.foreground.neutral.tertiary,
})}
/>
</AccordionSummaryContent>
}
>
TrailingContent, Icon<br />
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
trailingContent={
<AccordionSummaryContent variant="icon-button" rotate>
<IconButton>
<IconChevronDown
sx={(theme) => ({
color: theme.semantic.foreground.neutral.primary,
})}
/>
</IconButton>
</AccordionSummaryContent>
}
>
TrailingContent, IconButton, Rotate
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
trailingContent={
<AccordionSummaryContent
variant="icon-button"
>
<IconButton
as="a"
href="https://www.wanted.co.kr"
target="_blank"
onClick={(e) => {
e.stopPropagation();
}}
>
<IconArrowRight />
</IconButton>
</AccordionSummaryContent>
}
>
TrailingContent, IconButton<br />
trailingContent onClick
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
</FlexBox>
)
}
export default Demo;labelTrailing을 사용해서 레이블 우측에 콘텐츠를 추가할 수 있습니다.
콘텐츠를 추가할 때는 AccordionSummaryLabelTrailing으로 래핑해서 사용합니다.
아래 variant들을 사용합니다.
- verified-check
- content-badge
- custom
import { Accordion, AccordionSummary, AccordionDetails, AccordionDescription, AccordionSummaryLabelTrailing, ContentBadge, FlexBox } from '@montage-ui/core';
const Demo = () => {
return (
<FlexBox flexDirection="column" gap="12px" sx={{ width: '100%' }}>
<Accordion>
<AccordionSummary
labelTrailing={
<AccordionSummaryLabelTrailing variant="verified-check" />
}
>
LabelTrailing, Verified check
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
labelTrailing={
<AccordionSummaryLabelTrailing variant="content-badge">
<ContentBadge color="neutral">Badge</ContentBadge>
</AccordionSummaryLabelTrailing>
}
>
LabelTrailing, Content badge
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
</FlexBox>
)
}
export default Demo;extraContent를 사용해서 텍스트 영역 하단에 추가 콘텐츠를 추가할 수 있습니다.
콘텐츠를 추가할 때는 AccordionSummaryExtraContent로 래핑해서 사용합니다.
아래 variant들을 사용합니다.
- text
- content-badge
- custom
import { Accordion, AccordionSummary, AccordionDetails, AccordionDescription, AccordionSummaryExtraContent, ContentBadge, FlexBox } from '@montage-ui/core';
const Demo = () => {
return (
<FlexBox flexDirection="column" gap="12px" sx={{ width: '100%' }}>
<Accordion>
<AccordionSummary
extraContent={
<AccordionSummaryExtraContent variant="text">
Extra text
</AccordionSummaryExtraContent>
}
>
ExtraContent, Text
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary
extraContent={
<AccordionSummaryExtraContent variant="content-badge">
<ContentBadge color="neutral">Badge</ContentBadge>
</AccordionSummaryExtraContent>
}
>
ExtraContent, Content badge
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
</FlexBox>
)
}
export default Demo;AccordionSummary의 verticalPadding, variant로 간격을 조정할 수 있습니다.
import { Accordion, AccordionSummary, AccordionDetails, AccordionDescription, FlexBox } from '@montage-ui/core';
const Demo = () => {
return (
<FlexBox flexDirection="column" gap="12px" sx={{ width: '100%' }}>
<Accordion>
<AccordionSummary variant="full">
Variant, full
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion divider={false}>
<AccordionSummary>
Divider, false
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary>
VerticalPadding, Large (default)
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary verticalPadding="medium">
VerticalPadding, Medium
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary verticalPadding="small">
VerticalPadding, Small
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
</FlexBox>
)
}
export default Demo;Accordion을 중첩해서 사용할 수 있습니다.
중첩 인터렉션 영역이 잘리는 경우가 생길 수 있습니다.
disableAnimation를 사용하거나 하위 Accordion은variant="full"로 사용하여 인터렉션 영역을 보호할 수 있습니다.
import { FlexBox, Accordion, AccordionSummary, AccordionDetails, AccordionDescription } from '@montage-ui/core';
import type { CSSProperties } from 'react';
const Demo = () => {
return (
<FlexBox gap="12px" flexDirection="column" sx={{ width: '100%' }}>
<Accordion disableAnimation>
<AccordionSummary>
최상위 Accordion, disableAnimation
</AccordionSummary>
<AccordionDetails sx={{ gap: '4px' }}>
<Accordion divider={false} disableAnimation>
<AccordionSummary>
하위 Accordion, disableAnimation
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion divider={false} disableAnimation>
<AccordionSummary>
하위 Accordion, disableAnimation
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary variant="full">
최상위 Accordion, variant full
</AccordionSummary>
<AccordionDetails sx={{ gap: '4px', padding: 0 }}>
<Accordion divider={false}>
<AccordionSummary variant="full">
하위 Accordion, variant full
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
<Accordion divider={false}>
<AccordionSummary variant="full">
하위 Accordion, variant full
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
</AccordionDetails>
</Accordion>
</AccordionDetails>
</Accordion>
</FlexBox>
)
}
export default Demo;AccordionContent를 이용하여 AccordionDetails 내부에 콘텐츠를 추가할 수 있습니다.
import { Accordion, AccordionSummary, AccordionDetails, AccordionDescription, AccordionContent, TextButton } from '@montage-ui/core';
import { IconExternalLink } from '@montage-ui/icon';
const Demo = () => {
return (
<Accordion sx={{ width: '100%' }}>
<AccordionSummary>
제목
</AccordionSummary>
<AccordionDetails>
<AccordionDescription>
제목에 대한 상세 내용을 입력해주세요.<br />
긴 컨텐츠라면 접은 상태를 기본 값으로 사용하세요.
</AccordionDescription>
<AccordionContent>
<TextButton
size="small"
color="assistive"
trailingContent={<IconExternalLink />}
>
자세히 알아보기
</TextButton>
</AccordionContent>
</AccordionDetails>
</Accordion>
)
}
export default Demo;WAI-ARIA Accordion Pattern 을 준수합니다.
ListCell과 동일한 props를 사용합니다.
ListCellContent과 유사한 props를 사용합니다.
ListCellLabelTrailing과 동일한 props를 사용합니다.
ListCellExtraContent와 동일한 props를 사용합니다.
Typography와 동일한 props를 사용합니다.
