import React, { ChangeEvent, ReactNode, useCallback, useEffect, useMemo, useRef, useState, } from "react"; import TreeSelect, { TreeSelectProps as SelectProps } from "rc-tree-select"; import { TreeSelectContainer, DropdownStyles, StyledIcon, InputContainer, } from "./index.styled"; import "rc-tree-select/assets/index.less"; import { DefaultValueType, LabelValueType } from "rc-tree-select/lib/interface"; import { TreeNodeProps } from "rc-tree-select/lib/TreeNode"; import { CheckedStrategy } from "rc-tree-select/lib/utils/strategyUtil"; import { RenderMode, RenderModes, TextSize } from "constants/WidgetConstants"; import { Alignment, Button, Classes, InputGroup } from "@blueprintjs/core"; import { getMainCanvas, labelMargin, WidgetContainerDiff, } from "widgets/WidgetUtils"; import Icon from "components/ads/Icon"; import { Colors } from "constants/Colors"; import { LabelPosition } from "components/constants"; import LabelWithTooltip from "components/ads/LabelWithTooltip"; import { BackDrop } from "widgets/MultiSelectWidgetV2/component"; import Select from "rc-select"; export interface TreeSelectProps extends Required< Pick< SelectProps, | "disabled" | "placeholder" | "loading" | "dropdownStyle" | "allowClear" | "options" > > { value?: DefaultValueType; onChange: (value?: DefaultValueType, labelList?: ReactNode[]) => void; expandAll: boolean; mode: CheckedStrategy; labelText: string; labelAlignment?: Alignment; labelPosition?: LabelPosition; labelWidth?: number; labelTextColor?: string; labelTextSize?: TextSize; labelStyle?: string; compactMode: boolean; dropDownWidth: number; width: number; isValid: boolean; borderRadius: string; boxShadow?: string; accentColor: string; widgetId: string; filterText?: string; isFilterable: boolean; renderMode?: RenderMode; } const getSvg = (expanded: boolean) => ( ); const switcherIcon = (treeNode: TreeNodeProps) => { if (treeNode.isLeaf) { return ( ); } return getSvg(treeNode.expanded); }; const FOCUS_TIMEOUT = 500; function MultiTreeSelectComponent({ accentColor, allowClear, borderRadius, boxShadow, compactMode, disabled, dropdownStyle, dropDownWidth, expandAll, filterText, isFilterable, isValid, labelAlignment, labelPosition, labelStyle, labelText, labelTextColor, labelTextSize, labelWidth, loading, mode, onChange, options, placeholder, renderMode, value, widgetId, width, }: TreeSelectProps): JSX.Element { const [key, setKey] = useState(Math.random()); const [filter, setFilter] = useState(filterText ?? ""); const _menu = useRef(null); const selectRef = useRef | null>(null); const labelRef = useRef(null); const inputRef = useRef(null); const popupContainer = useRef(null); const [memoDropDownWidth, setMemoDropDownWidth] = useState(0); // treeDefaultExpandAll is uncontrolled after first render, // using this to force render to respond to changes in expandAll useEffect(() => { setKey(Math.random()); }, [expandAll]); // Get PopupContainer with is main Canvas useEffect(() => { const parent = getMainCanvas(); popupContainer.current = parent; }, []); const clearButton = useMemo( () => filter ? (