컴포넌트
Autocomplete
텍스트 입력에 추천 항목을 표시합니다.
설치
pnpm dlx ply-ui add autocomplete공통 설치 설정을 먼저 적용합니다.
사용법
items가 추천 후보입니다. 선택을 강제해야 한다면 Combobox 사용을 검토합니다.
Input의 aria-label과 Empty의 빈 결과 문구를 앱에 맞게 바꾸세요.
구성
| 구성 요소 | 역할 |
|---|---|
Root | 추천 항목과 입력 문자열을 관리합니다. |
Input | 직접 텍스트를 입력하는 영역입니다. |
Trigger / Clear | 추천 목록을 열거나 입력을 지웁니다. |
Portal / Positioner / Popup | 추천 목록의 위치와 표면을 구성합니다. |
List / Item | 추천 목록과 입력할 후보입니다. |
Empty | 추천 결과가 없을 때 표시합니다. |
Group / GroupLabel | 추천 항목의 그룹과 이름입니다. |
입력값 제어
value와 onValueChange로 입력 문자열을 관리합니다. 추천에 없는 문자열도 유지됩니다.
구현 코드
components/ui/autocomplete.tsx
"use client";
import type { ComponentProps } from "react";
import { Autocomplete as Primitive } from "@base-ui/react/autocomplete";
import { withClassName } from "../../lib/cx";
import "./autocomplete.css";
// 동작과 접근성은 Base UI가 담당합니다. 이 파일은 스타일 연결만 담당합니다.
function AutocompleteInput({
className,
...props
}: ComponentProps<typeof Primitive.Input>) {
return (
<Primitive.Input
{...props}
className={withClassName("rbx-input", className)}
/>
);
}
function AutocompleteTrigger({
className,
...props
}: ComponentProps<typeof Primitive.Trigger>) {
return (
<Primitive.Trigger
{...props}
className={withClassName("rbx-button", className)}
/>
);
}
function AutocompletePopup({
className,
...props
}: ComponentProps<typeof Primitive.Popup>) {
return (
<Primitive.Popup
{...props}
className={withClassName("rbx-popup", className)}
/>
);
}
function AutocompletePositioner({
className,
...props
}: ComponentProps<typeof Primitive.Positioner>) {
return (
<Primitive.Positioner
{...props}
className={withClassName("rbx-positioner", className)}
/>
);
}
function AutocompleteItem({
className,
...props
}: ComponentProps<typeof Primitive.Item>) {
return (
<Primitive.Item
{...props}
className={withClassName("rbx-option", className)}
/>
);
}
function AutocompleteEmpty({
className,
...props
}: ComponentProps<typeof Primitive.Empty>) {
return (
<Primitive.Empty
{...props}
className={withClassName("rbx-description", className)}
/>
);
}
function AutocompleteGroupLabel({
className,
...props
}: ComponentProps<typeof Primitive.GroupLabel>) {
return (
<Primitive.GroupLabel
{...props}
className={withClassName("rbx-group-label", className)}
/>
);
}
function AutocompleteClear({
className,
...props
}: ComponentProps<typeof Primitive.Clear>) {
return (
<Primitive.Clear
{...props}
className={withClassName("rbx-icon-button", className)}
/>
);
}
// Root/Portal 등 스타일 없는 파트와 제네릭 API는 원본을 그대로 보존합니다.
export const Autocomplete = {
...Primitive,
Input: AutocompleteInput,
Trigger: AutocompleteTrigger,
Popup: AutocompletePopup,
Positioner: AutocompletePositioner,
Item: AutocompleteItem,
Empty: AutocompleteEmpty,
GroupLabel: AutocompleteGroupLabel,
Clear: AutocompleteClear,
};
components/ui/autocomplete.css
@import "./button.css";
/* Autocomplete uses shared input and popup styles in theme.css. */