Components related to selecting items from a list
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The Select component allows users to choose one item from a dropdown list with optional filtering capabilities.
React component for single item selection from a dropdown list.
/**
* Select component for choosing one item from a dropdown list
* @template T - Type of items in the list
*/
class Select<T> extends React.Component<SelectProps<T>, SelectState> {
/** Generic factory method for type inference */
static ofType<U>(): new (props: SelectProps<U>) => Select<U>;
/** Reference to the input element */
inputElement: HTMLInputElement | null;
}
interface SelectProps<T> extends ListItemsProps<T>, SelectPopoverProps {
/** Child element that triggers the popover (typically a button) */
children?: React.ReactNode;
/** Whether the select is disabled */
disabled?: boolean;
/** Whether the select should fill its container */
fill?: boolean;
/** Whether to show a filter input in the dropdown */
filterable?: boolean;
/** Props for the filter input when filterable is true */
inputProps?: Partial<Omit<InputGroupProps, "value" | "onChange">>;
/** Props for the dropdown menu container */
menuProps?: React.HTMLAttributes<HTMLUListElement>;
/** Placeholder text for the filter input */
placeholder?: string;
/** Whether to reset the query when the popover closes */
resetOnClose?: boolean;
}
interface SelectState {
/** Whether the dropdown is currently open */
isOpen: boolean;
}Usage Examples:
import React, { useState } from "react";
import { Select, ItemRenderer } from "@blueprintjs/select";
import { Button, MenuItem } from "@blueprintjs/core";
interface City {
name: string;
country: string;
population: number;
}
const cities: City[] = [
{ name: "New York", country: "USA", population: 8400000 },
{ name: "London", country: "UK", population: 9000000 },
{ name: "Tokyo", country: "Japan", population: 14000000 },
];
const renderCity: ItemRenderer<City> = (city, { handleClick, modifiers, query }) => (
<MenuItem
key={`${city.name}-${city.country}`}
text={`${city.name}, ${city.country}`}
label={city.population.toLocaleString()}
onClick={handleClick}
active={modifiers.active}
disabled={modifiers.disabled}
/>
);
const CitySelect = () => {
const [selectedCity, setSelectedCity] = useState<City | null>(null);
return (
<Select<City>
items={cities}
itemRenderer={renderCity}
onItemSelect={setSelectedCity}
noResults={<MenuItem disabled text="No cities found." />}
filterable
resetOnClose
>
<Button
text={selectedCity ? `${selectedCity.name}, ${selectedCity.country}` : "Select a city..."}
rightIcon="caret-down"
/>
</Select>
);
};
// With custom filtering
const cityPredicate = (query: string, city: City) => {
return (
city.name.toLowerCase().includes(query.toLowerCase()) ||
city.country.toLowerCase().includes(query.toLowerCase())
);
};
const FilteredCitySelect = () => (
<Select<City>
items={cities}
itemRenderer={renderCity}
itemPredicate={cityPredicate}
onItemSelect={(city) => console.log("Selected:", city)}
>
<Button text="Select city with custom filter..." rightIcon="caret-down" />
</Select>
);Select components support extensive popover customization through SelectPopoverProps.
interface SelectPopoverProps {
/** Props passed to the popover content container */
popoverContentProps?: React.HTMLAttributes<HTMLDivElement>;
/** Props passed to the Blueprint Popover component */
popoverProps?: Partial<Omit<PopoverProps, "content" | "defaultIsOpen" | "fill" | "renderTarget">>;
/** Ref to access the popover instance */
popoverRef?: React.RefObject<Popover>;
/** Props passed to the popover target element */
popoverTargetProps?: React.HTMLAttributes<HTMLElement>;
}Usage Examples:
import { Select } from "@blueprintjs/select";
import { Button } from "@blueprintjs/core";
// Customize popover positioning and behavior
const CustomPopoverSelect = () => (
<Select<string>
items={["Option 1", "Option 2", "Option 3"]}
itemRenderer={(item, { handleClick, modifiers }) => (
<div onClick={handleClick} style={{ padding: "8px" }}>
{item}
</div>
)}
onItemSelect={(item) => console.log(item)}
popoverProps={{
position: "bottom-left",
minimal: true,
modifiers: {
preventOverflow: { enabled: true },
},
}}
popoverContentProps={{
style: { minWidth: "200px" },
}}
>
<Button text="Custom popover..." />
</Select>
);Select supports both item-level and list-level filtering predicates.
// From common types
type ItemPredicate<T> = (query: string, item: T, index?: number, exactMatch?: boolean) => boolean;
type ItemListPredicate<T> = (query: string, items: T[]) => T[];Usage Examples:
// Item predicate - filters individual items
const itemPredicate: ItemPredicate<City> = (query, city, index, exactMatch) => {
if (exactMatch) {
return city.name.toLowerCase() === query.toLowerCase();
}
return (
city.name.toLowerCase().includes(query.toLowerCase()) ||
city.country.toLowerCase().includes(query.toLowerCase())
);
};
// List predicate - custom sorting and filtering
const itemListPredicate: ItemListPredicate<City> = (query, cities) => {
if (!query) return cities;
const filtered = cities.filter(city =>
city.name.toLowerCase().includes(query.toLowerCase()) ||
city.country.toLowerCase().includes(query.toLowerCase())
);
// Sort by relevance
return filtered.sort((a, b) => {
const aStartsWithQuery = a.name.toLowerCase().startsWith(query.toLowerCase());
const bStartsWithQuery = b.name.toLowerCase().startsWith(query.toLowerCase());
if (aStartsWithQuery && !bStartsWithQuery) return -1;
if (!aStartsWithQuery && bStartsWithQuery) return 1;
return a.name.localeCompare(b.name);
});
};
const AdvancedFilterSelect = () => (
<Select<City>
items={cities}
itemRenderer={renderCity}
itemListPredicate={itemListPredicate}
onItemSelect={(city) => console.log("Selected:", city)}
filterable
>
<Button text="Advanced filtering..." />
</Select>
);