import React, {
ReactNode,
useCallback,
useEffect,
useRef,
useState,
} from "react";
import TreeSelect, { TreeSelectProps as SelectProps } from "rc-tree-select";
import {
TreeSelectContainer,
DropdownStyles,
inputIcon,
StyledLabel,
TextLabelWrapper,
} from "./index.styled";
import "rc-tree-select/assets/index.less";
import { DefaultValueType } from "rc-tree-select/lib/interface";
import { TreeNodeProps } from "rc-tree-select/lib/TreeNode";
import { CheckedStrategy } from "rc-tree-select/lib/utils/strategyUtil";
import {
CANVAS_CLASSNAME,
MODAL_PORTAL_CLASSNAME,
TextSize,
} from "constants/WidgetConstants";
import { Classes } from "@blueprintjs/core";
export interface TreeSelectProps
extends Required<
Pick<
SelectProps,
| "disabled"
| "options"
| "placeholder"
| "loading"
| "dropdownStyle"
| "allowClear"
>
> {
value?: DefaultValueType;
onChange: (value?: DefaultValueType, labelList?: ReactNode[]) => void;
expandAll: boolean;
mode: CheckedStrategy;
labelText?: string;
labelTextColor?: string;
labelTextSize?: TextSize;
labelStyle?: string;
compactMode: boolean;
}
const getSvg = (style = {}) => (
);
const switcherIcon = (treeNode: TreeNodeProps) => {
if (treeNode.isLeaf) {
return (
);
}
return getSvg({ transform: `rotate(${treeNode.expanded ? 90 : 0}deg)` });
};
function MultiTreeSelectComponent({
allowClear,
compactMode,
disabled,
dropdownStyle,
expandAll,
labelStyle,
labelText,
labelTextColor,
labelTextSize,
loading,
mode,
onChange,
options,
placeholder,
value,
}: TreeSelectProps): JSX.Element {
const [key, setKey] = useState(Math.random());
const _menu = useRef(null);
// treeDefaultExpandAll is uncontrolled after first render,
// using this to force render to respond to changes in expandAll
useEffect(() => {
setKey(Math.random());
}, [expandAll]);
const getDropdownPosition = useCallback(() => {
const node = _menu.current;
if (Boolean(node?.closest(`.${MODAL_PORTAL_CLASSNAME}`))) {
return document.querySelector(
`.${MODAL_PORTAL_CLASSNAME}`,
) as HTMLElement;
}
return document.querySelector(`.${CANVAS_CLASSNAME}`) as HTMLElement;
}, []);
const onClear = useCallback(() => onChange([], []), []);
return (
}
>
{labelText && (
{labelText}
)}
`+${e.length} more`}
multiple
notFoundContent="No Results Found"
onChange={onChange}
onClear={onClear}
placeholder={placeholder}
showArrow
showCheckedStrategy={mode}
showSearch
style={{ width: "100%" }}
switcherIcon={switcherIcon}
transitionName="rc-tree-select-dropdown-slide-up"
treeCheckable={
}
treeData={options}
treeDefaultExpandAll={expandAll}
treeIcon
treeNodeFilterProp="label"
value={value}
/>
);
}
export default MultiTreeSelectComponent;