# Searchable Term/Authority Picker Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the native `` used `w-full rounded border px-2 py-1 text-sm`; the popup should look like a menu surface). Concrete starting implementation (adjust class details to match the app's look; keep the structure): ```tsx import * as React from "react"; import { Combobox as ComboboxPrimitive } from "@base-ui/react/combobox"; import { cn } from "@/lib/utils"; function ComboboxRoot(props: ComboboxPrimitive.Root.Props) { return ; } function ComboboxInputGroup({ className, ...props }: ComboboxPrimitive.InputGroup.Props) { return ( ); } function ComboboxInput({ className, ...props }: ComboboxPrimitive.Input.Props) { return ( ); } function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) { return ( ); } function ComboboxTrigger({ className, ...props }: ComboboxPrimitive.Trigger.Props) { return ( ); } function ComboboxPopup({ className, ...props }: ComboboxPrimitive.Popup.Props) { return ( ); } function ComboboxList(props: ComboboxPrimitive.List.Props) { return ; } function ComboboxItem({ className, ...props }: ComboboxPrimitive.Item.Props) { return ( ); } function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) { return ( ); } export { ComboboxRoot, ComboboxInputGroup, ComboboxInput, ComboboxClear, ComboboxTrigger, ComboboxPopup, ComboboxList, ComboboxItem, ComboboxEmpty, }; ``` If a part's `.Props` type path differs (verify against the d.ts), adjust the type annotation — do **not** fall back to `any`. (`--anchor-width` is Base UI's positioner CSS var for matching the input width; if it isn't exposed under that name, use `min-w-[12rem]` instead — confirm when you run the story.) - [ ] **Step 2: Write `OptionsCombobox`** `web/src/objects/options-combobox.tsx` — the drop-in with the exact contract of the old `OptionsSelect`. It converts between the rhf `value` (id string) and the Base UI item object, and filters/displays by active-locale label. ```tsx import type { components } from "../api/schema"; import { ComboboxRoot, ComboboxInputGroup, ComboboxInput, ComboboxClear, ComboboxTrigger, ComboboxPopup, ComboboxList, ComboboxItem, ComboboxEmpty, } from "@/components/ui/combobox"; type LabelView = components["schemas"]["LabelView"]; export type Option = { id: string; labels: LabelView[] }; function labelIn(labels: LabelView[], lang: string): string { return ( labels.find((l) => l.lang === lang)?.label ?? labels.find((l) => l.lang === "en")?.label ?? labels[0]?.label ?? "" ); } export function OptionsCombobox({ id, value, onChange, options, lang, placeholder, }: { id: string; value: string; onChange: (v: string) => void; options: Option[]; lang: string; placeholder: string; }) { const selected = options.find((o) => o.id === value) ?? null; return ( items={options} value={selected} onValueChange={(option) => onChange(option?.id ?? "")} itemToStringLabel={(option) => (option ? labelIn(option.labels, lang) : "")} isItemEqualToValue={(a, b) => a?.id === b?.id} > {placeholder} {(option: Option) => ( {labelIn(option.labels, lang)} )} ); } ``` Notes: - `labelIn` is duplicated here from `field-input.tsx`. In Task 2 you will **export `labelIn` from a shared spot** (see Task 2 Step 3) and import it in both — for now define it locally so this file compiles standalone; Task 2 dedupes. - Confirm the generic on `ComboboxRoot