# List
URL: /react/components/list
Source: https://github.com/daangn/seed-design/blob/dev/docs/content/react/components/list.mdx
가로 행으로 구성된 콘텐츠를 표현하는 컴포넌트입니다.
사용 가능 버전: @seed-design/react@0.2.3, @seed-design/css@0.2.3
## Preview
```tsx
import { List, ListDivider, ListItem } from "seed-design/ui/list";
import { ListHeader } from "seed-design/ui/list-header";
import {
IconILowercaseSerifCircleLine,
IconPersonCircleLine,
} from "@karrotmarket/react-monochrome-icon";
import { Icon, VStack } from "@seed-design/react";
export default function ListPreview() {
return (
리스트 헤더} />}
title="아이콘이 있는 리스트 아이템"
detail="부가 정보가 포함된 설명"
suffix={} />}
/>
);
}
```
## Installation
- npm: npx @seed-design/cli@latest add ui:list
- pnpm: pnpm dlx @seed-design/cli@latest add ui:list
- yarn: yarn dlx @seed-design/cli@latest add ui:list
- bun: bun x @seed-design/cli@latest add ui:list
## Usage
```tsx
import { ListHeader } from "seed-design/ui/list-header";
import { List, ListItem } from "seed-design/ui/list";
리스트 헤더
```
## Props
### `ListHeader`
### `List`
[`VStackProps`](/react/components/layout/v-stack#props)와 동일합니다.
### List Items
[`DividerProps`](/react/components/divider#props)와 동일하나, 기본적으로 `
`로 렌더링됩니다. `List`를 `fieldset` 등으로 바꿔 사용하는 경우 `ListDivider` 역시 적절한 태그로 교체해주세요.
## Examples
### Using `ListHeader`
`ListHeader`는 `List` 밖에 위치합니다.
```tsx
import { List, ListButtonItem } from "seed-design/ui/list";
import { ListHeader } from "seed-design/ui/list-header";
import { ActionButton } from "seed-design/ui/action-button";
import {
IconChevronRightLine,
IconLockLine,
IconPersonCircleLine,
IconQuestionmarkCircleFill,
} from "@karrotmarket/react-monochrome-icon";
import { Divider, Icon, PrefixIcon, VStack } from "@seed-design/react";
export default function () {
return (
variant="mediumWeak"
} />}
suffix={} size="18px" />}
/>
} />}
suffix={} size="x4_5" />}
/>
variant="boldSolid"
} />}
suffix={} size="18px" />}
/>
} />}
suffix={} size="x4_5" />}
/>
List Header with Action Button
} />
도움말
} />}
suffix={} size="18px" />}
/>
} />}
suffix={} size="x4_5" />}
/>
);
}
```
### Affixes (Prefix/Suffix)
```tsx
import {
IconArrowUpBracketDownFill,
IconILowercaseSerifCircleLine,
} from "@karrotmarket/react-monochrome-icon";
import { Icon } from "@seed-design/react";
import { useState } from "react";
import { ActionButton } from "seed-design/ui/action-button";
import { Avatar } from "seed-design/ui/avatar";
import { IdentityPlaceholder } from "seed-design/ui/identity-placeholder";
import { List, ListDivider, ListItem } from "seed-design/ui/list";
import { ToggleButton } from "seed-design/ui/toggle-button";
export default function ListAffixes() {
const [isToggleButtonPressed, setIsToggleButtonPressed] = useState(false);
return (
}
/>
}
title="Prefix에 Avatar 넣기"
detail="Amet elit ullamco magna."
/>
} />}
/>
액션 버튼
}
/>
} />
}
/>
{isToggleButtonPressed ? "선택됨" : "토글 버튼"}
}
/>
);
}
```
### Clickable List Items
`ListButtonItem` 또는 `ListLinkItem`를 사용해서 리스트 항목 전체를 클릭 가능하도록 만들 수 있습니다.
`prefix` 또는 `suffix`에 클릭할 수 있는 요소를 포함하는 경우 `z-index: 1`, `position: relative`, `isolation: isolate` 등의 스타일을 적용하여 클릭 이벤트가 리스트 항목과 별개로 동작하도록 하세요. `ActionButton`, `ToggleButton` 등 SEED React 컴포넌트는 추가적으로 스타일을 적용하지 않아도 됩니다.
```tsx
import {
IconArrowUpRightLine,
IconCheckmarkFill,
IconChevronRightLine,
IconPenHorizlineFill,
IconPlusFill,
IconSquare2StackedFill,
} from "@karrotmarket/react-monochrome-icon";
import { PrefixIcon, Icon, Box } from "@seed-design/react";
import { useCallback, useState } from "react";
import { List, ListDivider, ListItem, ListButtonItem, ListLinkItem } from "seed-design/ui/list";
import { ActionButton } from "seed-design/ui/action-button";
import { ToggleButton } from "seed-design/ui/toggle-button";
const href = "https://www.daangn.com";
export default function ListClickable() {
const [isSubscribed, setIsSubscribed] = useState(false);
const [isCopied, setIsCopied] = useState(false);
const onCopyClick = useCallback(() => {
navigator.clipboard.writeText(href);
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000);
}, []);
return (
alert("편집 클릭됨")}
>
} />
편집
}
/>
alert("리스트 아이템 클릭됨")}
suffix={
<>
: } />
{isSubscribed ? "모아보는 중" : "모아보기"}
} />
>
}
/>
alert("리스트 아이템 클릭됨")}
suffix={
<>
} />
>
}
/>
: } />
{isCopied ? "복사됨" : "URL 복사"}
} />
>
}
href={href}
target="_blank"
rel="noreferrer"
/>
);
}
```
### `input`s in List Items
`ListSwitchItem`, `ListCheckItem`, `ListRadioItem`을 사용해서 리스트 항목에 `input` 요소를 포함할 수 있습니다. 이때, [Switchmark](/react/components/switch#using-switchmark), [Checkmark](/react/components/checkbox#using-checkmark) 또는 [Radiomark](/react/components/radio-group#using-radiomark)와 같은 컨트롤 요소를 `prefix`나 `suffix` 영역에 넣어 사용합니다.
```tsx
import { IconTrashcanLine } from "@karrotmarket/react-monochrome-icon";
import { IconSparkle2 } from "@karrotmarket/react-multicolor-icon";
import { Icon } from "@seed-design/react";
import { List, ListDivider, ListSwitchItem } from "seed-design/ui/list";
import { Switchmark } from "seed-design/ui/switch";
export default function ListSwitch() {
return (
} />}
suffix={}
/>
} />}
suffix={}
defaultChecked
/>
);
}
```
```tsx
import { Badge, HStack } from "@seed-design/react";
import { List, ListDivider, ListCheckItem } from "seed-design/ui/list";
import { Checkmark } from "seed-design/ui/checkbox";
export default function ListCheckbox() {
return (
알림 수신 동의권장
}
detail="푸시 알림을 받으시겠습니까?"
suffix={}
defaultChecked
/>
}
title="마케팅 정보 수신 동의"
detail="마케팅 정보를 받으시겠습니까?"
defaultChecked
/>
}
title="Ghost Variant"
/>
);
}
```
```tsx
import { RadioGroup } from "@seed-design/react/primitive";
import { List, ListDivider, ListRadioItem } from "seed-design/ui/list";
import { Radiomark } from "seed-design/ui/radio-group";
export default function ListRadio() {
return (
}
/>
}
value="option2"
title="옵션 2"
detail="두 번째 선택지"
/>
}
value="option3"
title="옵션 3"
detail="세 번째 선택지"
/>
);
}
```
### Accessibility
`List`는 기본적으로 `
`입니다. `ListCheckItem`와 `ListRadioItem`를 사용하는 경우 `List`에 적절한 role을 부여해야 합니다.
```tsx
{/* [!code highlight] */}
}
title="알림 수신 동의"
detail="푸시 알림을 받으시겠습니까?"
/>
}
title="마케팅 정보 수신 동의"
detail="마케팅 정보를 받으시겠습니까?"
/>
```
```tsx
{/* [!code highlight] */}
{/*
*/}
}
value="짜장"
title="짜장"
/>
}
value="짬뽕"
title="짬뽕"
/>
```
### Disabled
```tsx
import {
IconChevronRightLine,
IconPersonCircleLine,
IconSlashCircleLine,
} from "@karrotmarket/react-monochrome-icon";
import { Divider, Icon, VStack } from "@seed-design/react";
import { RadioGroup } from "@seed-design/react/primitive";
import { List, ListButtonItem, ListCheckItem, ListRadioItem } from "seed-design/ui/list";
import { Checkmark } from "seed-design/ui/checkbox";
import { Radiomark } from "seed-design/ui/radio-group";
export default function ListDisabled() {
return (
} />}
title="활성화된 ListButtonItem"
detail="Cupidatat et pariatur amet."
suffix={} />}
/>
} />}
title="활성화된 ListCheckItem"
suffix={}
/>
} />}
title="활성화된 ListRadioItem"
suffix={}
value="foo"
/>
} />}
title="비활성화된 ListButtonItem"
detail="Cupidatat et pariatur amet."
suffix={} />}
/>
} />}
title="비활성화된 ListCheckItem"
suffix={}
/>
} />}
title="비활성화된 ListRadioItem"
suffix={}
value="foo"
/>
);
}
```
### Variants
#### Highlighted
```tsx
import { IconPersonCircleLine } from "@karrotmarket/react-monochrome-icon";
import { Box, Icon, VStack } from "@seed-design/react";
import { useState } from "react";
import { List, ListDivider, ListItem, ListButtonItem } from "seed-design/ui/list";
import { Switch } from "seed-design/ui/switch";
export default function ListHighlighted() {
const [highlighted, setHighlighted] = useState(true);
return (
} />}
title="버튼"
detail="Enim aute duis magna mollit aute sit aliquip duis ut tempor sunt."
onClick={() => {}}
/>
} />}
title="하이라이트된 버튼"
detail="Enim aute duis magna mollit aute sit aliquip duis ut tempor sunt."
onClick={() => {}}
/>
} />}
title="하이라이트 및 비활성화된 버튼"
detail="Enim aute duis magna mollit aute sit aliquip duis ut tempor sunt."
onClick={() => {}}
/>
} />}
title="하이라이트"
highlighted={highlighted}
/>
);
}
```
### With Bottom Sheet
```tsx
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet";
import { ActionButton } from "seed-design/ui/action-button";
import { Checkmark } from "seed-design/ui/checkbox";
import { List, ListCheckItem } from "seed-design/ui/list";
import { PrefixIcon, VStack } from "@seed-design/react";
import { useState } from "react";
import { IconArrowClockwiseCircularFill } from "@karrotmarket/react-monochrome-icon";
const TYPES = ["버스", "지하철", "택시", "자전거", "도보"] as const;
export default function ListBottomSheet() {
const [isOpen, setIsOpen] = useState(false);
const [selectedTypes, setSelectedTypes] = useState<(typeof TYPES)[number][]>([]);
return (
BottomSheet 열기
);
}
```
### Alignment
`alignItems` prop으로 `prefix`와 `suffix`의 정렬 방식을 조정할 수 있습니다.
```tsx
import { List, ListItem } from "seed-design/ui/list";
import { HStack } from "@seed-design/react";
import { IdentityPlaceholder } from "seed-design/ui/identity-placeholder";
import { Avatar } from "seed-design/ui/avatar";
export default function ListAlignment() {
return (
} />}
title="Prefix에 Avatar 넣기. Veniam elit velit esse ea incididunt sunt sit aute."
detail="Et proident sit ullamco ut voluptate. Voluptate eiusmod occaecat adipisicing quis qui esse."
/>
} />}
title="Prefix에 Avatar 넣고 상단으로 정렬하기. Veniam elit velit esse ea incididunt sunt sit aute."
detail="일반적으로 `title`이 길어질 때 `alignItems`를 `flex-start`로 설정합니다."
/>
);
}
```
### Border Radius
`List`에 `itemBorderRadius` prop을 설정하여 active 상태에서 적용되는 리스트 항목의 radius를 조정할 수 있습니다. 리스트가 카드 등 모서리가 둥근 컨테이너 안에 포함되는 경우 유용합니다.
```tsx
import { List, ListCheckItem, ListRadioItem } from "seed-design/ui/list";
import { ListHeader } from "seed-design/ui/list-header";
import { Checkmark } from "seed-design/ui/checkbox";
import { Radiomark } from "seed-design/ui/radio-group";
import { HStack, VStack } from "@seed-design/react";
import { RadioGroup } from "@seed-design/react/primitive";
export default function ListBorderRadius() {
return (
카드 borderRadius: r3_5}
/>
}
/>
카드 borderRadius: 22px}
/>
}
/>
);
}
```
## Customization and Composition
### Usage
@seed-design/react 패키지에서 제공하는 `List`와 `ListHeader` 컴포넌트는 다음과 같은 구조로 사용됩니다.
```
ListHeader
List.Root
└── List.Item
├── List.Prefix (선택사항)
├── List.Content
│ ├── List.Title
│ └── List.Detail (선택사항)
└── List.Suffix (선택사항)
└── List.Item
├── ...
```
```tsx
import { ListHeader, List, Icon } from "@seed-design/react";
내 정보
} />
내 프로필다른 사람들에게 보이는 내 정보를 관리합니다.} />
{/* ... */}
```
- `ListHeader`: 리스트의 제목이나 설명을 표시하는 헤더 역할
- `List.Root`: 모든 리스트 항목을 감싸는 컨테이너 역할
- `List.Item`: 개별 리스트 항목. 클릭 가능한 영역을 정의
- `List.Prefix`: 아이콘, [Avatar](/react/components/avatar), [Checkmark](/react/components/checkbox#using-checkmark) 등을 표시할 수 있는 시작 영역
- `List.Content`: 주요 콘텐츠가 들어가는 중앙 영역
- `List.Title`: 리스트 항목의 제목
- `List.Detail`: 부가 설명이나 세부 정보
- `List.Suffix`: 아이콘, [Action Button](/react/components/action-button), [Toggle Button](/react/components/toggle-button) 등을 표시할 수 있는 끝 영역
### `asChild` prop으로 적절한 시맨틱 요소와 조합하기
`asChild` prop에 대해 자세히 알아봅니다.
#### Using `asChild` prop in `List.Content`
리스트 항목 전체 영역을 클릭 가능한 버튼으로 만드는 경우 활용할 수 있는 패턴입니다. 이 경우 `List.Item`에 `asChild` prop을 사용하지 않도록 유의하세요. `List.Prefix` 또는 `List.Suffix`에 버튼을 넣는 경우 `button`이 중첩되는 등 유효하지 않은 HTML이 생성됩니다.
```tsx
import { List as SeedList } from "@seed-design/react";
{/* [!code highlight] */}
{/* [!code highlight] */}
{/* [!code highlight] */}
alert("보기 클릭됨")}
>
보기
```
[Snippet](/react/components/concepts/snippet)으로 제공되는 `ListButtonItem` 및 `ListLinkItem`는 이 패턴을 쉽게 구현할 수 있도록 돕습니다.
```tsx
import { ListButtonItem } from "seed-design/ui/list";
alert("사용자 클릭됨")}
title="사용자"
detail="항목 6개"
suffix={
alert("보기 클릭됨")}
>
보기
}
/>
```
#### Using `asChild` prop in `List.Item`
리스트 항목 전체 영역을 `label`로 만들고, `List.Prefix` 또는 `List.Suffix`에 [Switchmark](/react/components/switch#using-switchmark), [Checkmark](/react/components/checkbox#using-checkmark) 또는 [Radiomark](/react/components/radio-group#using-radiomark)를 넣는 경우 활용할 수 있는 패턴입니다.
```tsx
import { List as SeedList } from "@seed-design/react";
import { Checkbox } from "@seed-design/react/primitive";
{/* [!code highlight] */}
{/*
```
[Snippet](/react/components/concepts/snippet)으로 제공되는 `ListSwitchItem`, `ListCheckItem` 및 `ListRadioItem`는 이 패턴을 쉽게 구현할 수 있도록 돕습니다.
```tsx
import { ListCheckItem } from "seed-design/ui/list";
}
/>
```