Components
react-tree-multi-select allows you to customize its built-in components
by providing your own custom components as a property.
This feature enables you to tailor the appearance and behavior of various components.
The general pattern for implementing a custom component involves creating a component
and passing the attributes prop to the root element.
Here's a simple implementation:
const CustomChipLabel: FC<ChipLabelProps> = (props) => (
<div {...props.attributes}>
{/*your custom code here*/}
</div>
);You must pass attributes prop to the root element in order for component to work properly.
If you would like to add custom CSS class to component, you can merge component classname with your own like in the example below:
const CustomChipLabel: FC<ChipLabelProps> = (props) => (
<div {...props.attributes} className={`${props.attributes.className} custom-classname`}>
{/*your custom code here*/}
</div>
);Built-in components
You can import and reuse built-in components from the library for additional flexibility (except of Footer,
since it has empty implementation by default).
For an example, refer to the CustomChipContainer.
const CustomChipContainer: FC<ChipContainerProps> = (props) => (
<>
<Tooltip id="chip-tooltip" render={({content}) => (<span>{content}</span>)}/>
<components.ChipContainer
{...props}
attributes={{
...props.attributes,
"data-tooltip-id": "chip-tooltip",
"data-tooltip-content": `Tooltip for the ${props.ownProps.label}`,
"data-tooltip-place": "top"
}}/>
</>
);Custom props
You can pass your own properties to the component through the props object. When creating a custom component, you can access these properties and use them in your implementation.
To improve performance, make sure to memoize components prop (and other props like objects, arrays, or callbacks).
This helps prevent unnecessary re-renders by ensuring prop references remain stable between renders.
const components: Components = useMemo(() => (
{
ChipLabel: {
component: CustomChipLabel,
props: {suffix: 'Yo'}
}
}
), []);For an example, refer to the CustomChipLabel.
TypeScript support
You can use generic parameters to strongly type each component, ensuring type safety and preventing accidental misuse.
- Component type entries can be listed in any order. The order of keys in the generic argument does not matter — TypeScript will correctly match each one by name.
- Only known component keys (
Field,Footer,NodeContainer, etc.) are allowed. - Each component’s props are strongly typed according to the generics you specify.
- Extra or unknown keys (like WrongComponent) or mismatched types will result in a TypeScript error.
- Extra or unknown fields inside the component config (like wrongProp) are disallowed.
const createComponents = (label: string): Components<{ Field: FieldType<CustomFieldProps>; }> => ({
Field: {
component: CustomField,
props: {label},
},
});For an example, refer to the CustomField.
Field
Let's say you have filters on a page that, when clicked, open a dropdown with a range of filter options.
It can be achieved by providing custom Field component like in the example below.
Your custom Field component must either be focusable itself or contain exactly one focusable child to ensure
proper keyboard navigation.
ChipContainer
Custom ChipContainer component example.
ChipLabel
Custom ChipLabel component example.
ChipClear
Custom ChipClear component example.
Input
Custom Input component example.
FieldClear
Custom FieldClear component example.
FieldToggle
Custom FieldToggle component example.
Dropdown
Custom Dropdown component example.
SelectAllContainer
Custom SelectAllContainer component example.
SelectAllCheckbox
Custom SelectAllCheckbox component example.
SelectAllLabel
Custom SelectAllLabel component example.
NodeContainer
Custom NodeContainer component example.
NodeToggle
Custom NodeToggle component example.
NodeCheckbox
Custom NodeCheckbox component example.
NodeLabel
Custom NodeLabel component example.
Footer
An optional custom component rendered at the bottom of the dropdown, scrolling together with the items.
The default implementation is null, so the Footer is not rendered unless explicitly provided.
You can use the Footer to implement features like pagination.
By default, the Footer is not shown during search (when the input has a value) or when there are no items in the
dropdown.
This behavior can be customized using the footerConfig prop.
NoData
Custom NoData component example.