tree-select ui component for react
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The main TreeSelect component providing a comprehensive tree selection interface with dropdown functionality, supporting both single and multiple selection, checkable nodes, search, async loading, and performance optimizations.
Main tree-select component with generic type parameters for value and option types.
/**
* Main TreeSelect component for hierarchical data selection
* @template ValueType - Type of the selection value(s)
* @template OptionType - Type of tree node data extending DataNode
*/
declare const TreeSelect: <ValueType = any, OptionType extends DataNode = DataNode>(
props: TreeSelectProps<ValueType, OptionType> & React.RefAttributes<BaseSelectRef>
) => React.ReactElement;
interface TreeSelectProps<ValueType = any, OptionType extends DataNode = DataNode> {
// Basic configuration
prefixCls?: string;
id?: string;
className?: string;
style?: React.CSSProperties;
disabled?: boolean;
placeholder?: string;
// Value management
value?: ValueType;
defaultValue?: ValueType;
onChange?: (value: ValueType, labelList: React.ReactNode[], extra: ChangeEventExtra) => void;
labelInValue?: boolean;
maxCount?: number;
// Selection configuration
multiple?: boolean;
treeCheckable?: boolean | React.ReactNode;
treeCheckStrictly?: boolean;
showCheckedStrategy?: CheckedStrategy;
// Data source
treeData?: OptionType[];
children?: React.ReactNode;
treeDataSimpleMode?: boolean | SimpleModeConfig;
fieldNames?: FieldNames;
// Tree expansion
treeDefaultExpandAll?: boolean;
treeExpandedKeys?: SafeKey[];
treeDefaultExpandedKeys?: SafeKey[];
onTreeExpand?: (expandedKeys: SafeKey[]) => void;
treeExpandAction?: ExpandAction;
// Search & filtering
searchValue?: string;
/** @deprecated Use searchValue instead */
inputValue?: string;
onSearch?: (value: string) => void;
autoClearSearchValue?: boolean;
filterTreeNode?: boolean | ((inputValue: string, treeNode: DataNode) => boolean);
treeNodeFilterProp?: string;
treeNodeLabelProp?: string;
// Async loading
loadData?: (dataNode: LegacyDataNode) => Promise<unknown>;
treeLoadedKeys?: SafeKey[];
onTreeLoad?: (loadedKeys: SafeKey[]) => void;
// Tree appearance
treeTitleRender?: (node: OptionType) => React.ReactNode;
treeLine?: boolean;
treeIcon?: IconType;
showTreeIcon?: boolean;
switcherIcon?: IconType;
treeMotion?: any;
// Dropdown configuration
open?: boolean;
onDropdownVisibleChange?: (open: boolean) => void;
dropdownStyle?: React.CSSProperties;
dropdownClassName?: string;
dropdownMatchSelectWidth?: boolean | number;
dropdownAlign?: AlignType;
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
// Performance & virtualization
virtual?: boolean;
listHeight?: number;
listItemHeight?: number;
listItemScrollOffset?: number;
// Event handlers
onSelect?: (value: ValueType, option: OptionType) => void;
onDeselect?: (value: ValueType, option: OptionType) => void;
onClear?: () => void;
onFocus?: (e: React.FocusEvent) => void;
onBlur?: (e: React.FocusEvent) => void;
onPopupScroll?: (e: React.UIEvent) => void;
// Additional props
allowClear?: boolean;
showSearch?: boolean;
notFoundContent?: React.ReactNode;
maxTagCount?: number | 'responsive';
maxTagPlaceholder?: React.ReactNode;
maxTagTextLength?: number;
loading?: boolean;
direction?: 'ltr' | 'rtl';
tabIndex?: number;
}TreeSelect exposes methods through React ref for programmatic control.
interface BaseSelectRef {
/** Focus the select input */
focus: () => void;
/** Remove focus from the select input */
blur: () => void;
/** Scroll to specific position in dropdown list */
scrollTo: (config: ScrollConfig) => void;
}
interface ScrollConfig {
index?: number;
key?: SafeKey;
align?: 'top' | 'bottom' | 'auto';
offset?: number;
}Usage Examples:
import TreeSelect from "rc-tree-select";
import { useRef } from "react";
// Single selection with tree data
function SingleSelectExample() {
const [value, setValue] = useState("0-0-0");
const treeData = [
{
key: "0-0",
value: "0-0",
title: "Parent Node",
children: [
{ key: "0-0-0", value: "0-0-0", title: "Child Node 1" },
{ key: "0-0-1", value: "0-0-1", title: "Child Node 2" },
],
},
];
return (
<TreeSelect
style={{ width: 300 }}
value={value}
treeData={treeData}
treeDefaultExpandAll
onChange={setValue}
placeholder="Select node"
/>
);
}
// Multiple selection with checkboxes
function MultipleSelectExample() {
const [value, setValue] = useState<string[]>([]);
return (
<TreeSelect
style={{ width: 300 }}
value={value}
treeData={treeData}
multiple
treeCheckable
showCheckedStrategy={SHOW_PARENT}
placeholder="Select multiple nodes"
onChange={setValue}
/>
);
}
// Async data loading
function AsyncLoadingExample() {
const [value, setValue] = useState();
const loadData = (node: DataNode) => {
return new Promise<void>((resolve) => {
setTimeout(() => {
// Simulate async data loading
node.children = [
{ key: `${node.key}-0`, value: `${node.key}-0`, title: 'Child 1' },
{ key: `${node.key}-1`, value: `${node.key}-1`, title: 'Child 2' },
];
resolve();
}, 1000);
});
};
return (
<TreeSelect
style={{ width: 300 }}
value={value}
treeData={[
{ key: "0", value: "0", title: "Expandable Node", isLeaf: false },
]}
loadData={loadData}
onChange={setValue}
/>
);
}
// Search and filtering
function SearchableExample() {
const [value, setValue] = useState();
const [searchValue, setSearchValue] = useState("");
return (
<TreeSelect
style={{ width: 300 }}
value={value}
searchValue={searchValue}
treeData={treeData}
showSearch
filterTreeNode={(inputValue, treeNode) =>
treeNode.title?.toString().toLowerCase().includes(inputValue.toLowerCase())
}
onChange={setValue}
onSearch={setSearchValue}
placeholder="Search and select"
/>
);
}
// LabelInValue mode
function LabelInValueExample() {
const [value, setValue] = useState<{ label: string; value: string }>();
return (
<TreeSelect
style={{ width: 300 }}
value={value}
treeData={treeData}
labelInValue
treeDefaultExpandAll
onChange={setValue}
placeholder="Select with label"
/>
);
}
// Using ref methods
function RefMethodsExample() {
const selectRef = useRef<BaseSelectRef>(null);
const handleFocus = () => {
selectRef.current?.focus();
};
return (
<div>
<button onClick={handleFocus}>Focus TreeSelect</button>
<TreeSelect
ref={selectRef}
style={{ width: 300 }}
treeData={treeData}
placeholder="Controlled focus"
/>
</div>
);
}// Change event information
interface ChangeEventExtra {
preValue: SafeKey[];
triggerValue: SafeKey;
triggerNode: DataNode;
selected?: boolean;
checked?: boolean;
}
// Icon type for tree display
type IconType = React.ReactNode | ((props: any) => React.ReactNode);
// Legacy data node for backward compatibility
interface LegacyDataNode extends DataNode {
props?: any;
}
// Expand action type for tree interactions
type ExpandAction = 'click' | 'doubleClick';
// Alignment configuration for dropdown positioning
interface AlignType {
points?: string[];
offset?: number[];
targetOffset?: number[];
overflow?: {
adjustX?: boolean;
adjustY?: boolean;
};
}Install with Tessl CLI
npx tessl i tessl/npm-rc-tree-select