`No routing lane matched “${query}”. Try a broader keyword or create a new lane.`
}
items={[...teamItems]}
loading={isSearching}
loadingMessage="Searching routing lanes…"
onSearchValueChange={setSearchValue}
searchPlaceholder="Type at least 3 characters"
searchValue={searchValue}
/>
This pattern is useful when the results come from an API and you need a clear
transition between loading, empty, and selectable states.
);
}
function LaunchRoutingForm() {
const [submitted, setSubmitted] = useState | null>(null);
const form = useForm<{ team: string }>({
defaultValues: {
team: ""
}
});
return (
);
}
const meta = {
title: "Components/Combobox",
component: ControlledDemo,
parameters: {
docs: {
description: {
component:
"Combobox is the searchable single-select surface for longer option sets, recent picks, and async lookup flows. The list should feel gently staged as results appear, with active rows gliding into place instead of snapping."
}
},
layout: "centered"
},
tags: ["autodocs"]
} satisfies Meta;
export default meta;
type Story = StoryObj;
export const Controlled: Story = {
render: () =>
};
export const RecentAndSuggested: Story = {
render: () =>
};
export const AsyncResults: Story = {
parameters: {
docs: {
description: {
story:
"Async comboboxes should crossfade between loading, empty, and result states. Keep the motion short and directional so the user understands the state change without losing the current context."
}
}
},
render: () =>
};
export const WithForm: Story = {
render: () =>
};