Accordion
관련된 정보 섹션을 접고 펼쳐 화면을 간결하게 구성하는 컴포넌트입니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion className="accordion-preview">
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">첫 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">두 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Installation
npx @seed-design/cli@latest add ui:accordionpnpm dlx @seed-design/cli@latest add ui:accordionyarn dlx @seed-design/cli@latest add ui:accordionbun x @seed-design/cli@latest add ui:accordion의존성 설치
npm install @karrotmarket/lynx-monochrome-icon @seed-design/lynx-reactyarn add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-reactpnpm add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-reactbun add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react아래 코드를 복사 후 붙여넣고 사용하세요
/**
* @file ui:accordion
* @requires @seed-design/lynx-react@>=0.5.0 <1.0.0
* @requires @seed-design/lynx-css@>=0.9.0 <1.0.0
* @requires @karrotmarket/lynx-monochrome-icon@>=1.20.0 <2.0.0
**/
import IconChevronDownSmallLine from "@karrotmarket/lynx-monochrome-icon/IconChevronDownSmallLine";
import * as React from "@lynx-js/react";
import { Accordion as SeedAccordion } from "@seed-design/lynx-react";
import type { LynxIconElementProps } from "@seed-design/lynx-react";
export interface AccordionProps extends SeedAccordion.RootProps {}
/**
* @see https://seed-design.io/lynx/components/accordion
*/
export const Accordion = React.forwardRef<unknown, AccordionProps>((props, ref) => {
const { children, ...otherProps } = props;
return (
<SeedAccordion.Root ref={ref} {...otherProps}>
{children}
</SeedAccordion.Root>
);
});
Accordion.displayName = "Accordion";
export interface AccordionItemProps extends SeedAccordion.ItemProps {}
/**
* @see https://seed-design.io/lynx/components/accordion
*/
export const AccordionItem = React.forwardRef<unknown, AccordionItemProps>((props, ref) => {
const { children, ...otherProps } = props;
return (
<SeedAccordion.Item ref={ref} {...otherProps}>
{children}
</SeedAccordion.Item>
);
});
AccordionItem.displayName = "AccordionItem";
export interface AccordionTriggerProps extends Omit<SeedAccordion.TriggerProps, "children"> {
title: React.ReactNode;
description?: React.ReactNode;
prefix?: React.ReactNode;
suffixIcon?: React.ReactElement<LynxIconElementProps>;
}
/**
* @see https://seed-design.io/lynx/components/accordion
*/
export const AccordionTrigger = React.forwardRef<unknown, AccordionTriggerProps>((props, ref) => {
const {
title,
description,
prefix,
suffixIcon = <IconChevronDownSmallLine />,
"accessibility-label": accessibilityLabel,
...otherProps
} = props;
return (
<SeedAccordion.Header>
<SeedAccordion.Trigger
ref={ref}
accessibility-label={accessibilityLabel ?? (typeof title === "string" ? title : undefined)}
{...otherProps}
>
{prefix != null ? <SeedAccordion.Prefix>{prefix}</SeedAccordion.Prefix> : null}
<SeedAccordion.Body>
<SeedAccordion.Title>{title}</SeedAccordion.Title>
{description != null ? (
<SeedAccordion.Description>{description}</SeedAccordion.Description>
) : null}
</SeedAccordion.Body>
<SeedAccordion.SuffixIcon icon={suffixIcon} />
</SeedAccordion.Trigger>
</SeedAccordion.Header>
);
});
AccordionTrigger.displayName = "AccordionTrigger";
export interface AccordionContentProps extends SeedAccordion.ContentProps {}
/**
* @see https://seed-design.io/lynx/components/accordion
*/
export const AccordionContent = React.forwardRef<unknown, AccordionContentProps>((props, ref) => {
const { children, ...otherProps } = props;
return (
<SeedAccordion.Content ref={ref} {...otherProps}>
{children}
</SeedAccordion.Content>
);
});
AccordionContent.displayName = "AccordionContent";
/**
* This file is a snippet from SEED Design, helping you get started quickly with @seed-design/* packages.
* You can extend this snippet however you want.
*/
Props
Accordion
Prop
Type
values?string[] | undefineddefaultValues?string[] | undefinedonValuesChange?((values: string[]) => void) | undefineddisabled?boolean | undefinedmultiple?boolean | undefinedstyle?CSSProperties | undefinedchildren?React.ReactNodeclassName?string | undefinedAccordionItem
Prop
Type
valuestringdisabled?boolean | undefinedstyle?CSSProperties | undefinedchildren?React.ReactNodeclassName?string | undefinedAccordionTrigger
Prop
Type
titleReact.ReactNodedescription?React.ReactNodeprefix?React.ReactNodesuffixIcon?React.ReactElement<LynxIconElementProps, string | React.JSXElementConstructor<any>> | undefinedclassName?string | undefinedbindtap?EventHandler<BaseTouchEvent<Target>> | undefinedexpandedAccessibilityValue?string | undefinedcollapsedAccessibilityValue?string | undefinedstyle?CSSProperties | undefinedAccordionContent
Prop
Type
style?CSSProperties | undefinedchildren?React.ReactNodeclassName?string | undefinedExamples
Inline Variant
기본 variant입니다. 아이템이 연속된 흐름으로 제공되며, 아이템 사이에 구분선이 표시됩니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion variant="inline">
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">첫 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">두 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Separated
variant="separated" 를 사용하면 각 항목이 분리된 카드 형태로 표시됩니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion variant="separated">
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">첫 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">두 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Multiple
기본적으로 한 번에 하나의 항목만 펼칠 수 있습니다. multiple prop을 사용하면 여러 항목을 동시에 펼칠 수 있습니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion multiple defaultValues={["item-1", "item-2"]}>
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">여러 항목을 동시에 펼칠 수 있습니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">각 항목은 다른 항목과 독립적으로 열고 닫힙니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Always one open
values와 onValuesChange를 사용해 controlled 패턴으로 운영하면, 빈 배열이 들어올 때 setter를 호출하지 않는 가드만 추가하여 항상 하나의 항목이 열려 있도록 강제할 수 있습니다.
import "./styles";
import { useState } from "@lynx-js/react";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
const [values, setValues] = useState<string[]>(["item-1"]);
function handleValuesChange(nextValues: string[]) {
"background only";
if (nextValues.length === 0) return;
setValues(nextValues);
}
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion values={values} onValuesChange={handleValuesChange}>
<AccordionItem value="item-1">
<AccordionTrigger title="주문 전 확인 사항" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
현재 항목은 다시 눌러도 닫히지 않고, 다른 항목을 선택할 때만 전환됩니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="배송 일정" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
평일 오후 2시 이전 주문은 당일 출고되며, 주말 주문은 다음 영업일에 출고됩니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="교환 및 반품" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
수령 후 7일 이내에 교환 또는 반품을 요청할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Size
size로 Accordion의 크기를 정합니다. (default: medium)
Lynx에서는 medium과 large를 사용할 수 있습니다. 화면 너비에 따라 자동으로 바뀌는 responsive는 지원하지 않으므로, 필요하면 앱에서 화면 너비에 따라 두 값 중 하나를 선택해 주세요.
import "./styles";
import { Box, Text, VStack, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<VStack width="full" gap="spacingY.componentDefault">
<Accordion size="medium">
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목" description="size=medium (default)" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
<Accordion size="large">
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목" description="size=large" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</VStack>
</view>
);
}Prefix
prefix prop에 아이콘 같은 앞쪽 요소를 전달할 수 있습니다.
import "./styles";
import IconCardLine from "@karrotmarket/lynx-monochrome-icon/IconCardLine";
import IconQuestionmarkCircleLine from "@karrotmarket/lynx-monochrome-icon/IconQuestionmarkCircleLine";
import IconTruckLine from "@karrotmarket/lynx-monochrome-icon/IconTruckLine";
import { Box, Icon, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion>
<AccordionItem value="shipping">
<AccordionTrigger
prefix={<Icon icon={<IconTruckLine />} size="full" />}
title="배송 방법"
/>
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
일반 배송, 빠른 배송, 방문 수령 중 주문 상황에 맞는 방법을 선택할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="payment">
<AccordionTrigger
prefix={<Icon icon={<IconCardLine />} size="full" />}
title="결제 및 쿠폰"
/>
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
카드, 간편결제, 보유 쿠폰을 한 번에 확인하고 결제에 적용할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="support">
<AccordionTrigger
prefix={<Icon icon={<IconQuestionmarkCircleLine />} size="full" />}
title="문의와 환불"
/>
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
주문 취소 가능 시간, 환불 소요 기간, 고객센터 문의 방법을 확인할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Description
description prop으로 트리거에 부가 설명을 추가할 수 있습니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion>
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" description="항목에 대한 간략한 설명입니다." />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">첫 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" description="항목에 대한 간략한 설명입니다." />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">두 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" description="항목에 대한 간략한 설명입니다." />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Disabled
disabled prop으로 전체 또는 개별 항목을 비활성화할 수 있습니다.
Accordion에disabled를 설정하면 모든 항목이 비활성화됩니다.AccordionItem에disabled를 설정하면 해당 항목만 비활성화됩니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion>
<AccordionItem value="item-1">
<AccordionTrigger title="활성화된 항목" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">이 항목은 활성화 상태입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2" disabled>
<AccordionTrigger title="비활성화된 항목" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">이 항목은 비활성화 상태입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="활성화된 항목" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">이 항목은 활성화 상태입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Controlled
values와 onValuesChange를 사용하여 열림 상태를 직접 제어할 수 있습니다.
import "./styles";
import { useState } from "@lynx-js/react";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
const [values, setValues] = useState<string[]>(["item-1"]);
function handleValuesChange(nextValues: string[]) {
"background only";
setValues(nextValues);
}
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion values={values} onValuesChange={handleValuesChange}>
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">첫 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">두 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Value Array Changes
controlled 모드에서는 현재 열려 있는 항목이 values 배열로 전달됩니다. 아래 예시는 트리거를 누를 때마다 최신 values와 최근 onValuesChange 결과를 함께 보여줍니다.
import "./styles";
import { useState } from "@lynx-js/react";
import { Box, HStack, Text, VStack, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
const DEFAULT_VALUES = ["shipping"];
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
const [values, setValues] = useState<string[]>(DEFAULT_VALUES);
const [history, setHistory] = useState<string[][]>([DEFAULT_VALUES]);
function handleValuesChange(nextValues: string[]) {
"background only";
setValues(nextValues);
setHistory((previous) => [nextValues, ...previous].slice(0, 5));
}
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<HStack className="accordion-preview__value-changes" gap="x6" align="flexStart">
<Box flexGrow width="full" minWidth="0">
<Accordion multiple values={values} onValuesChange={handleValuesChange}>
<AccordionItem value="shipping">
<AccordionTrigger title="배송 옵션" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
빠른 배송, 새벽 배송, 방문 수령 옵션을 비교할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="payment">
<AccordionTrigger title="결제 수단" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
카드, 계좌이체, 간편결제 중에서 원하는 결제 수단을 선택할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="refund">
<AccordionTrigger title="환불 정책" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">
주문 취소 가능 시간과 환불 소요 기간을 확인할 수 있습니다.
</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</Box>
<Box
className="accordion-preview__history"
p="x4"
bg="bg.layerBasement"
borderRadius="r2"
borderWidth={1}
borderColor="stroke.neutralWeak"
>
<VStack gap="x2" align="stretch">
<Text textStyle="t3Medium">values: {JSON.stringify(values)}</Text>
<Text textStyle="t3Medium">onValuesChange history:</Text>
{history.map((snapshot, index) => (
<Text key={`${snapshot.join(",") || "empty"}-${index}`} textStyle="t4Regular">
{index + 1}. {JSON.stringify(snapshot)}
</Text>
))}
</VStack>
</Box>
</HStack>
</view>
);
}Default Expanded
defaultValues를 사용하여 초기 열림 상태를 지정할 수 있습니다.
import "./styles";
import { Box, Text, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion multiple defaultValues={["item-1"]}>
<AccordionItem value="item-1">
<AccordionTrigger title="아코디언 항목 1" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">첫 번째 항목은 기본으로 펼쳐진 상태입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="아코디언 항목 2" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">두 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger title="아코디언 항목 3" />
<AccordionContent>
<Box p="x4">
<Text textStyle="t4Regular">세 번째 항목의 내용입니다.</Text>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Custom Content
AccordionContent는 열림/닫힘 애니메이션 컨테이너 역할만 합니다. 기본 패딩, 배경색, 테두리, 타이포그래피 스타일은 제공하지 않으므로 내부 콘텐츠에서 직접 구성해야 합니다. 아래 예시처럼 Box로 패딩과 배경을 명시적으로 주는 패턴을 권장합니다.
import "./styles";
import { Box, Text, VStack, useSeedClassName } from "@seed-design/lynx-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
export default function Example() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<view className={`${seedClassName} docs-lynx-accordion-root`}>
<Accordion>
<AccordionItem value="item-1">
<AccordionTrigger title="배송 안내" description="배송 정책 및 예상 소요 시간" />
<AccordionContent>
<Box p="x4">
<Box p="x4" borderRadius="r3" bg="bg.layerBasement">
<VStack gap="x3" align="stretch">
<VStack gap="x1" align="stretch">
<Text textStyle="t5Bold">일반 배송</Text>
<Text textStyle="t5Regular">주문 후 영업일 기준 2-3일 내에 배송됩니다.</Text>
</VStack>
<Box p="x3" borderRadius="r2" bg="bg.layerDefault">
<Text textStyle="t4Regular" color="fg.neutralSubtle">
제주 및 도서산간 지역은 1-2일이 추가 소요될 수 있습니다.
</Text>
</Box>
</VStack>
</Box>
</Box>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger title="반품 및 교환" description="반품/교환 절차 안내" />
<AccordionContent>
<Box p="x4">
<Box p="x4" borderRadius="r3" bg="bg.layerBasement">
<VStack gap="x2" align="stretch">
<Text textStyle="t5Regular">1. 고객센터로 반품/교환 요청</Text>
<Text textStyle="t5Regular">2. 상품 수거 (택배 방문 수거)</Text>
<Text textStyle="t5Regular">3. 검수 후 환불 또는 교환 처리</Text>
</VStack>
</Box>
</Box>
</AccordionContent>
</AccordionItem>
</Accordion>
</view>
);
}Web Version Differences
Lynx Accordion은 React 버전과 다음 차이가 있습니다.
- Native elements: HTML heading, button, region 대신 Lynx
<view>와<text>를 렌더링합니다. - Interaction: 키보드 탐색 대신 Trigger의 native tap 이벤트로 항목을 열고 닫습니다.
- Accessibility: DOM ARIA 대신
accessibility-heading,accessibility-role-description,accessibility-value를 사용합니다. - Responsive size: Lynx preset은 viewport media query를 지원하지 않아
size="responsive"를 제공하지 않습니다. - Content transition: React 버전은 CSS custom property로 높이를 전달하고, Lynx 버전은
layoutchange로 콘텐츠 높이를 측정해 같은 duration과 easing의 transition을 적용합니다.
Unsupported Lynx Features
| 기능 | 설명 |
|---|---|
asChild | Lynx에는 Slot 기반 polymorphic 렌더링이 없습니다. |
headingLevel | Lynx의 heading 접근성 속성은 HTML heading level을 받지 않습니다. |
| DOM ARIA 연결 | aria-controls, aria-labelledby, role="region" 대신 Lynx native 접근성 속성을 사용합니다. |
| Arrow / Home / End 키 탐색 | Lynx native 화면에는 웹과 같은 키보드 포커스 모델이 없습니다. |
size="responsive" | Lynx preset은 viewport media query를 지원하지 않습니다. |
Last updated on