Lynx

Select

트리거를 눌러 목록에서 값을 선택하는 컴포넌트입니다.

Engine ≥ 3.9<overlay>
사용 가능 버전@seed-design/[email protected], @seed-design/[email protected]
Lynx 예제를 불러오는 중입니다.

Installation

npx @seed-design/cli@latest add ui:select

Usage

SelectContent는 긴 목록을 스크롤합니다. container를 지정하지 않으면 Lynx view 안에, 지정하면 native overlay에 렌더링됩니다.

import {
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectRoot,
  SelectTrigger,
} from "@/components/ui/select";

export function App() {
  return (
    <view style={{ width: "240px" }}>
      <SelectRoot defaultValue={["apple"]}>
        <SelectTrigger accessibility-label="과일" placeholder="과일을 선택하세요" />
        <SelectContent>
          <SelectGroup>
            <SelectItem value="apple" label="사과" />
            <SelectItem value="banana" label="바나나" />
            <SelectItem value="cherry" label="체리" />
          </SelectGroup>
        </SelectContent>
      </SelectRoot>
    </view>
  );
}
  • multiple일 때는 항목을 탭해도 목록을 닫지 않고 선택 상태를 전환합니다.
  • SelectRoot의 문자열 label 또는 accessibility-label은 Trigger의 기본 접근성 이름으로 사용됩니다.
  • 목록을 열면 선택된 항목이 보이도록 스크롤하며, Trigger 주변의 여유 공간과 safe area에 맞춰 높이를 제한합니다.

Props

SelectRoot

Prop

Type

label?React.ReactNode
labelWeight?"medium" | "bold" | undefined
indicator?React.ReactNode
showRequiredIndicator?boolean | undefined
description?React.ReactNode
errorMessage?React.ReactNode
fieldRef?React.Ref<NodesRef> | undefined
size?"medium" | "large" | "responsive" | undefined
value?string[] | undefined
defaultValue?string[] | undefined
open?boolean | undefined
defaultOpen?boolean | undefined

SelectTrigger

Prop

Type

placeholder?React.ReactNode
prefixIcon?React.ReactElement<LynxIconElementProps, string | React.JSXElementConstructor<any>> | undefined
suffixIcon?React.ReactElement<LynxIconElementProps, string | React.JSXElementConstructor<any>> | undefined

SelectContent

Prop

Type

overlayLevel?1 | 4 | 2 | 3 | undefined

SelectGroup

Prop

Type

label?React.ReactNode

SelectItem

Prop

Type

labelReact.ReactNode
description?React.ReactNode
selectedIndicator?React.ReactNode
disabled?boolean | undefined
readOnly?boolean | undefined
valuestring
textValue?string | undefined

Examples

Size

size로 trigger와 목록의 크기를 정합니다. 기본값은 large이고, responsive는 native runtime의 화면 폭이 1280 이상이면 medium, 그 외에는 large로 해석합니다.

Lynx 예제를 불러오는 중입니다.

Groups

SelectGroup으로 옵션을 묶고 label로 그룹 제목을 표시합니다. 두 번째 그룹부터는 그룹 사이에 구분선이 추가됩니다.

Lynx 예제를 불러오는 중입니다.

Multiple Selection

multiple을 지정하면 선택한 옵션을 다시 탭해 해제할 수 있습니다. 다중 선택 중에는 목록이 닫히지 않으며 trigger에는 기본적으로 선택된 textValue가 ", "로 연결되어 표시됩니다.

Lynx 예제를 불러오는 중입니다.

With Description

SelectItem의 description으로 옵션에 부가 설명을 추가합니다.

Lynx 예제를 불러오는 중입니다.

With Prefix Icon

SelectItem의 prefixIcon으로 옵션 앞에 아이콘을 표시합니다. 단일 옵션이 선택되면 해당 아이콘이 trigger prefix에 표시됩니다. 선택이 없거나 여러 옵션이 선택된 경우에는 SelectTrigger의 prefixIcon fallback을 사용합니다.

Lynx 예제를 불러오는 중입니다.

Custom Item Label

label에는 복합 JSX를 전달할 수 있습니다. 복합 label을 사용할 때는 trigger에 표시할 문자열과 옵션 접근성 이름을 위해 textValue를 함께 지정하세요.

Lynx 예제를 불러오는 중입니다.

Disabled

SelectItem의 disabled는 특정 옵션을, SelectRoot의 disabled는 Select 전체를 비활성화합니다. readOnly도 목록을 열거나 선택을 바꾸지 않습니다.

Lynx 예제를 불러오는 중입니다.

Long List

목록은 상하 8px 패딩을 포함한 내용 높이만큼 표시하며, 별도의 최소 높이는 없습니다. 최대 높이는 480px이고 trigger 주위의 남은 공간과 safe area에 맞춰 제한합니다. 내용이 이 높이를 넘을 때만 스크롤됩니다.

열릴 때 선택된 옵션이 화면 밖에 있으면 보이는 데 필요한 만큼만 스크롤합니다. 이미 보이는 옵션을 선택하거나 목록이 닫히는 중에는 스크롤 위치를 바꾸지 않습니다.

Lynx 예제를 불러오는 중입니다.

Placement

placement로 목록 위치를 정합니다. 기본값은 bottom이며, 공간이 부족하면 native positioner가 반대쪽으로 뒤집거나 경계 안으로 이동합니다.

Lynx 예제를 불러오는 중입니다.

Listening to Value Changes

value와 onValueChange로 선택 값을 제어할 수 있습니다.

Lynx 예제를 불러오는 중입니다.

Controlled Open State

open과 onOpenChange로 목록 상태를 제어합니다. 초기 상태만 지정하려면 defaultOpen을 사용하세요.

Lynx 예제를 불러오는 중입니다.

Container

container를 지정하지 않으면 Select 레이어는 Lynx view 안의 position: fixed view로 렌더링되고, z-index 99로 같은 화면의 형제 요소 위에 그려집니다. container="window"처럼 native container 이름을 지정하면 native overlay에 렌더링되어 Lynx view 밖의 host 화면까지 덮습니다. overlayLevel은 container를 지정했을 때 overlay의 표시 순서를 정합니다.

두 방식 모두 레이어 바깥을 탭하면 아래 화면에 탭을 전달하지 않고 "interactOutside" reason으로 닫힙니다. 닫힌 동안에도 레이어를 숨긴 채 유지하므로 열기 전에도 defaultValue의 label과 아이콘을 trigger에 표시합니다.

Lynx 예제를 불러오는 중입니다.

onOpenChange Details

onOpenChange의 두 번째 인자는 상태를 바꾼 이유와 native event를 제공합니다.

  • 열림: "trigger"
  • 닫힘: "trigger", "itemSelect", "interactOutside"
  • container를 지정한 native overlay가 닫힘을 요청한 경우(Android 뒤로 가기): "dismiss". container가 없으면 전달하지 않으며, Android 뒤로 가기는 Select가 아니라 host 화면을 닫습니다.
Lynx 예제를 불러오는 중입니다.

Custom Value Format

formatValue로 trigger에 표시할 선택 값을 바꿉니다. callback은 value, label, textValue, icon, resolved를 담은 선택 item 배열을 받습니다. icon은 SelectItem의 prefixIcon이고, 목록에 없는 값은 resolved: false로 전달합니다.

Lynx 예제를 불러오는 중입니다.

Field Integration

SelectRoot는 기존 Lynx Field를 조합하므로 label, description, errorMessage, invalid, required와 showRequiredIndicator를 지원합니다. 오류 메시지가 있으면 description 대신 오류 메시지를 표시합니다.

Lynx 예제를 불러오는 중입니다.

Form Integration

Lynx에는 HTML <form>과 native <select> 제출 모델이 없습니다. 선택 값은 onValueChange로 앱 state에 저장하고, 제출 action의 payload에 그 값을 넣으세요.

React Hook Form

React Hook Form 통합은 제공하지 않습니다. value, onValueChange, invalid, errorMessage를 앱 상태에 연결하세요.

웹 버전과의 차이

  • Trigger는 native 요소이며 asChild를 제공하지 않습니다.
  • onOpenChange의 reason은 trigger, itemSelect, interactOutside, dismiss입니다.
  • 키보드 focus, typeahead, Escape 키 닫기는 지원하지 않습니다.
  • container를 지정하면 목록을 native overlay에 렌더링합니다.

Lynx 미지원 기능

  • HTML form 제출과 브라우저 validation은 지원하지 않습니다. onValueChange로 앱 상태를 갱신하고 제출 action에서 검증하세요.
  • React Hook Form 통합은 제공하지 않습니다. 값과 오류 상태를 앱 상태에 직접 연결하세요.
  • DOM focus, typeahead, ARIA id 연결은 지원하지 않습니다. native 접근성 속성과 host의 접근성 탐색을 사용하세요.

Last updated on

목차