Skip to Content

Lookup

기존에 존재하는 내부 또는 외부 데이터를 선택하기 위해 사용하는 입력 요소


개요

Lookup은 팝업을 통해 데이터를 조회하고 선택할 수 있는 입력 컴포넌트입니다. 사용자가 직접 값을 입력하지 않고, 조회 팝업에서 데이터를 선택하는 방식으로 동작합니다.

주요 특징

  • 기본 상태: 데이터 선택을 위한 입력 요소 제공
  • 포커스 상태: 포커스 시 시각적으로 구분되는 스타일
  • 읽기 전용 상태: 읽기 전용(readOnly) 시각적 구분
  • 오류 상태 표시: ariaInvalid 기반 에러 스타일
  • 디자인 토큰: 테마 커스터마이징 지원

Sizes

Lookup은 5가지 크기를 지원합니다. 기본값은 md입니다.


사용 예시

기본 상태

기존에 존재하는 내부 또는 외부 데이터를 선택하기 위해 사용하는 입력 요소를 제공합니다.

포커스 상태

포커스 시 시각적으로 구분되는 스타일을 제공합니다. Tab 키로 포커스하면 border와 ring 스타일이 적용됩니다.

읽기 전용 상태

읽기 전용(readOnly) 상태를 시각적으로 구분합니다. 클릭해도 팝업이 열리지 않습니다.

오류 상태 표시

ariaInvalid prop으로 오류 상태를 시각적으로 표현합니다.

프로젝트팀 구현 항목: 아래 기능은 프로젝트 요구사항에 맞춰 직접 구현합니다.

  • 팝업 호출: Lookup 버튼 클릭 시 데이터 조회 팝업 화면 표시
  • 선택 결과 반영: 팝업에서 데이터 선택 시 팝업 닫힘 및 선택 데이터 반영
  • Select/Cancel/Clear 버튼: 팝업 내 선택, 취소, 초기화 버튼 제공
  • 단일 행 선택: 데이터(Row) 클릭 시 단일 항목만 선택
  • 입력 방식 제한: 팝업에서만 값 선택 가능
  • 데이터 소스 연동: 내부/외부 API 데이터 조회
  • 입력 가능 제어: 읽기 전용 상태에서 선택 및 변경 제한

API Reference

Props

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"크기
valueT | null-선택된 값
displayValuestring-표시할 텍스트
placeholderstring"선택하세요"플레이스홀더 텍스트
disabledbooleanfalse비활성화 여부
readOnlybooleanfalse읽기 전용 여부
widthstring | number-너비
modalOptionsLookupModalOptions-팝업 모달 옵션
ariaInvalidboolean-오류 상태
classNamestring-추가 CSS 클래스
renderContent(props: LookupRenderProps<T>) => ReactNode필수팝업 콘텐츠 렌더 함수

Events

EventTypeDescription
onValueChange(value: T | null) => void값 변경 시 호출

LookupModalOptions

PropTypeDefaultDescription
titleReactNode-팝업 타이틀
descriptionReactNode-팝업 설명
classNamestring-팝업 추가 CSS 클래스
type"center" | "bottomsheet" | "fullscreen" | "sidepanel"-팝업 유형
dimboolean-배경 딤 처리 여부
allowInteractionboolean-딤 상태에서 뒤쪽 조작 허용
resizableboolean-팝업 리사이즈 가능 여부
showCloseButtonboolean-닫기 버튼 표시 여부
draggableboolean-팝업 드래그 가능 여부
footerAlign"left" | "center" | "right"-푸터 정렬
dedupeKeystring-동일 lookup 중복 방지용 식별자 (자세한 내용은 아래 참고)

미지정 시 DialogProvider의 전역 config 기본값이 적용됩니다.

LookupRenderProps

PropTypeDescription
select(value: T) => void값 선택 (팝업 닫힘)
cancel() => void선택 취소 (팝업 닫힘)
clear() => void값 초기화 (팝업 닫힘)

기본 사용법

import { Lookup } from "@vortex/ui-foundation" <Lookup value={selectedUser} displayValue={selectedUser?.name} onValueChange={setSelectedUser} placeholder="사용자 선택" modalOptions={{ title: "사용자 조회" }} renderContent={({ select, cancel, clear }) => ( <div> {users.map((user) => ( <div key={user.id} onClick={() => select(user)}>{user.name}</div> ))} </div> )} />

모달 옵션 활용

<Lookup value={selectedUser} displayValue={selectedUser?.name} onValueChange={setSelectedUser} placeholder="사용자 선택" modalOptions={{ title: "사용자 조회", dim: false, allowInteraction: true, resizable: true, type: "center", }} renderContent={({ select, cancel, clear }) => ( <div> {users.map((user) => ( <div key={user.id} onClick={() => select(user)}>{user.name}</div> ))} </div> )} />

중복 모달 방지 (dedupeKey)

Lookup 컴포넌트는 내부에서 인스턴스별 자동 dedupeKey 를 부여하여 같은 인스턴스에서 빠른 더블클릭으로 모달이 두 번 열리지 않도록 자동 차단합니다. (사용자가 별도 설정을 하지 않아도 동작합니다.)

다음과 같은 경우에는 호출자가 명시적으로 modalOptions.dedupeKey 를 지정해야 cross-instance 중복까지 차단할 수 있습니다.

  • 여러 트리거(다른 인스턴스 / 외부 버튼 / 단축키 등)에서 의미상 같은 lookup을 호출하는 경우
  • useDialog().lookup(...) 을 직접 호출하는 경우
  • dim: false, allowInteraction: true 로 배경 조작이 허용된 상태

modalOptions.dedupeKey (또는 useDialog().lookup({ dedupeKey })) 를 지정하면 동일 key 의 lookup이 이미 열려있을 때 새 모달을 띄우지 않고 즉시 Promise<null> 로 resolve 합니다. 사용자가 명시한 dedupeKey 가 있으면 자동 인스턴스 키 대신 명시값이 사용됩니다. 이미 열린 lookup은 그대로 유지되며, 자체 select/cancel 로만 닫힙니다.

<Lookup value={selectedUser} displayValue={selectedUser?.name} onValueChange={setSelectedUser} placeholder="사용자 선택" modalOptions={{ title: "사용자 조회", dim: false, allowInteraction: true, dedupeKey: "user-pick", }} renderContent={({ select, cancel }) => (...)} />

또는 store 를 직접 호출하는 경우:

const user = await useDialog.getState().lookup<User>({ dedupeKey: "user-pick", title: "사용자 조회", content: ({ select, cancel }) => (...), }) // user === null 인 경우: cancel 되었거나, 이미 동일 dedupeKey 의 lookup 이 열려있어 dedupe 로 차단된 호출

dedupeKey 미지정 호출은 기존과 동일하게 매번 별개 모달이 열립니다.

반환값 동작

케이스store PromiseLookup 컴포넌트의 onValueChange
select(value)valueonValueChange(value)
clear() (Lookup만)내부 CLEAR_SYMBOL 처리onValueChange(null)
cancel()null(호출 안 됨)
dedupeKey 로 차단됨null(호출 안 됨)

주의: dedupeKey 로 차단된 호출은 cancel 과 동일하게 null 로 resolve 됩니다. 호출자는 두 경우를 구분할 수 없습니다. 구분이 필요하면 호출 전에 외부 플래그/ref 로 in-flight 여부를 직접 확인하세요. clear 는 store 의 LookupHandlers 에는 존재하지 않으며, Lookup 컴포넌트가 CLEAR_SYMBOLselect 하는 wrapper 트릭으로 제공합니다.


접근성

키보드 네비게이션

  • Tab: Lookup 필드에 포커스 이동
  • Enter/Click: 조회 팝업 열기

권장 사항

  • displayValue로 선택된 값을 명확히 표시
  • placeholder로 입력 필드 목적 전달
  • ✅ 에러 상태 시 ariaInvalid 속성 사용
  • ❌ readOnly 상태에서 팝업 호출 방지

관련 컴포넌트

Last updated on