AddressSearch
The AddressSearch module provides you an input component that includes a
dropdown for autocomplete suggestions.
Usage
The component is controlled. That means that you are responsible to tell it which item is currently selected and which are visible in the dropdown.
An item in terms of this component is an object that contains at least two
properties: An id property that is unique among all the items that are
selected or visible and a label property, which will be shown when the item
is displayed.
You are of course allowed to pass objects as items that contain more than the required properties. If you use TypeScript, you can pass the type definition of your items as generic argument to the component:
const props = {
/* Define your props */
};
type CustomItem = { id: string; label: string; foo: number };
const Foo = () => <AddressSearch<CustomItem> {...props} />;
The accepted props are defined in the following table:
| Property name | Type | Required | Values | Default |
|---|---|---|---|---|
visibleItems | Item[] | ✅ | - | - |
onInputValueChange | InputValueChangeHandler | ✅ | - | - |
onSelect | SelectHandler | ✅ | - | - |
selectedItem | Item | ✅ | - | - |
id | string | - | - | |
name | string | - | - | |
placeholder | string | - | - | |
isLoading | boolean | - | - | |
labelId | string | - | - | |
usePxUnits | boolean | - | - |
Here are the complete type definitions:
type InputValueChangeHandler = (inputValue: string) => void;
type SelectHandler = (selectedItem: Item | null) => void;
Item is the type of the items used when rendering the component.
The props id, name, state and placeholder will be passed to the
InputBox which is used under the hood to render the styled
input field.
To listen on change events for the input field you can pass a handler via the
onInputValueChange prop. This function will be called with the new value of
the input as first argument.
To control the items shown in the dropdown below the input field you have to
pass the visibleItems prop. You can update the visible items based on the
current input value like this:
const [filteredItems, setFilteredItems] = useState<Item>(initialItems);
<AddressSearch
onInputValueChange={(newValue) => {
// Filter the values based on the new value.
setFilteredItems(initialItems.filter((item) => item.includes(newValue)));
// You can also use a debounce for server-side filtering.
}}
visibleItems={filteredItems}
{...otherProps}
/>;
Example
type Item = { id: string; label: string };
const items = [
{ id: "munich", label: "München" },
{ id: "london", label: "London" },
{ id: "sf", label: "San Francisco" },
];
const AddressSearchExample: React.FC = () => {
const [selectedItem, setSelectedItem] = useState<Item | null>(null);
const [filteredValues, setFilteredValues] = useState<Item[]>(items);
return (
<Spacings.Stack>
<label htmlFor="address-search">
<Text>Select an address</Text>
</label>
<AddressSearch
id="address-search"
onSelect={(item) => {
setSelectedItem(item);
}}
onInputValueChange={(newValue) => {
setFilteredValues(
items.filter((item) =>
item.label.toLowerCase().includes(newValue.toLowerCase()),
),
);
}}
selectedItem={selectedItem}
visibleItems={filteredValues}
/>
</Spacings.Stack>
);
};