fix(site): allow search by label in MultiSelectComboBox (#24421)

Relates to  https://linear.app/codercom/issue/CODAGT-103

- Add `keywords={[option.label]}` to `CommandItem` in
`MultiSelectCombobox` so cmdk's default filter matches against the
visible label text, not just the value (UUID)
- Extend `OpenCombobox` story with type-to-filter assertions
- Add "search filters by display name" step to `TemplateAllowlist` story

> 🤖

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Cian Johnston
2026-04-16 17:44:26 +01:00
committed by GitHub
co-authored by Copilot
parent 15d8e4ff9f
commit 383b10f71e
3 changed files with 70 additions and 4 deletions
@@ -31,11 +31,43 @@ export const Default: Story = {};
export const OpenCombobox: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(canvas.getByPlaceholderText("Select organization"));
const input = canvas.getByPlaceholderText("Select organization");
await userEvent.click(input);
await waitFor(() =>
expect(canvas.getByText("My Organization")).toBeInTheDocument(),
);
// Both options should be visible initially.
await waitFor(() => {
expect(
canvas.getByRole("option", { name: "My Organization" }),
).toBeInTheDocument();
expect(
canvas.getByRole("option", { name: "My Organization 2" }),
).toBeInTheDocument();
});
// Type a display name to filter — this verifies cmdk filters
// by label rather than by the underlying UUID value.
await userEvent.type(input, "My Organization 2");
await waitFor(() => {
expect(
canvas.getByRole("option", { name: "My Organization 2" }),
).toBeInTheDocument();
expect(
canvas.queryByRole("option", { name: /^My Organization$/ }),
).not.toBeInTheDocument();
});
// Clear the search and confirm both options reappear.
await userEvent.clear(input);
await waitFor(() => {
expect(
canvas.getByRole("option", { name: "My Organization" }),
).toBeInTheDocument();
expect(
canvas.getByRole("option", { name: "My Organization 2" }),
).toBeInTheDocument();
});
},
};
@@ -642,6 +642,7 @@ export const MultiSelectCombobox: React.FC<MultiSelectComboboxProps> = ({
<CommandItem
key={option.value}
value={option.value}
keywords={[option.label]}
disabled={option.disable}
onMouseDown={(e) => {
e.preventDefault();
@@ -60,6 +60,39 @@ export const TemplateAllowlist: Story = {
expect(saveBtn).toBeDisabled();
});
await step("search filters by display name", async () => {
const input = canvas.getByPlaceholderText("Select templates...");
await userEvent.click(input);
// Type a partial display name.
await userEvent.type(input, "Docker");
// The matching template should be visible.
await waitFor(() => {
expect(
canvas.getByRole("option", { name: "Docker Development" }),
).toBeVisible();
});
// A non-matching template should not be visible.
await waitFor(() => {
expect(
canvas.queryByRole("option", { name: "Kubernetes Production" }),
).not.toBeInTheDocument();
});
// Clear the search and verify the full list returns.
await userEvent.clear(input);
await waitFor(() => {
expect(
canvas.getByRole("option", { name: "Kubernetes Production" }),
).toBeVisible();
});
// Close dropdown by pressing Escape so the next step starts clean.
await userEvent.keyboard("{Escape}");
});
await step("select one template and save", async () => {
const input = canvas.getByPlaceholderText("Select templates...");
await userEvent.click(input);