/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
useCallback,
type ReactNode,
type CSSProperties,
useState,
} from 'react';
import classNames from 'classnames';
import {
ValueExpression,
ValueExpressionType,
type RefExpression,
type ViewVariableType,
} from '@coze-workflow/base';
import { type TreeNodeData } from '@coze-arch/bot-semi/Tree';
import { IconCozApply } from '@coze-arch/coze-design/icons';
import { IconButton, type TreeSelectProps } from '@coze-arch/coze-design';
import {
RefValueDisplay,
type RefTagColor,
type RefValueDisplayProps,
} from '@/form-extensions/components/value-expression-input/ref-value-display';
import {
type CustomFilterVar,
type VariableTreeDataNode,
type RenderDisplayVarName,
} from '@/form-extensions/components/tree-variable-selector/types';
import {
VariableSelector,
type VariableSelectorProps,
} from '@/form-extensions/components/tree-variable-selector';
export const useRefInputNode = ({
value,
onChange,
onBlur,
disabled,
variablesDataSource,
validateStatus,
readonly,
invalidContent,
renderDisplayVarName,
testId,
disabledTypes,
showClear = false,
customFilterVar,
setFocused,
style,
refTagColor,
hideDeleteIcon,
variableTagStyle,
optionFilter,
renderExtraOption,
enableSelectNode,
popoverStyle,
handleDataSource,
variableTypeConstraints,
}: {
value?: ValueExpression;
onChange: (v: ValueExpression | undefined) => void;
onBlur?: () => void;
disabled?: boolean;
variablesDataSource?: VariableTreeDataNode[];
validateStatus?: TreeSelectProps['validateStatus'];
readonly?: boolean;
testId?: string;
disabledTypes?: ViewVariableType[];
showClear?: boolean;
invalidContent?: string;
renderDisplayVarName?: RenderDisplayVarName;
customFilterVar?: CustomFilterVar;
setFocused?: (focused: boolean) => void;
style?: CSSProperties;
refTagColor?: RefTagColor;
hideDeleteIcon?: boolean;
variableTagStyle?: CSSProperties;
optionFilter?: VariableSelectorProps['optionFilter'];
handleDataSource?: VariableSelectorProps['handleDataSource'];
renderExtraOption?: (
data?: TreeNodeData[],
action?: {
hiddenPopover: () => void;
},
) => ReactNode;
enableSelectNode?: boolean;
popoverStyle?: CSSProperties;
/* 类型限制,引用类型不满足限制时,显示警告信息 */
variableTypeConstraints?: RefValueDisplayProps['variableTypeConstraints'];
}) => {
const onRefChange = useCallback(
(v: string[] | undefined): void => {
if (v === undefined) {
onChange(undefined);
} else {
onChange({
type: ValueExpressionType.REF,
content: { keyPath: v as string[] },
});
}
},
[onChange],
);
const handleRefRemove = () => {
onChange?.(undefined);
onBlur?.();
};
const [focused, setStateFocused] = useState(false);
const _setFocused = useCallback(
(v: boolean) => {
setStateFocused(v);
setFocused?.(v);
},
[setFocused],
);
const renderVariableSelect = (trigger: ReactNode) =>
readonly && trigger ? (
trigger
) : (