import React, { useEffect, useMemo, useRef, useState } from "react"; import { Input, InputRef } from "antd"; import { Node } from "@antv/x6"; import { useSafeState } from "ahooks"; export default function Text(props: { value: string; styles: React.CSSProperties & { bold: boolean; italic: boolean; }; node: Node; fixedWidth: boolean; placeholder?: string; txtStyle?: React.CSSProperties; onChange?: (value: string) => void; }) { const { value, styles, node, placeholder, txtStyle } = props; const [isEditing, setIsEditing] = useSafeState(false); const inputRef = useRef(null); const [labelText, setLabelText] = useState(value); useEffect(() => { setLabelText(value); }, [value]); const style = useMemo((): React.CSSProperties => { return { ...styles, fontWeight: styles.bold ? "bold" : undefined, fontStyle: styles.italic ? "italic" : undefined, minHeight: "12px", padding: 0, wordBreak: "break-all", }; }, [styles]); const handleChange = (val: string) => { // node.setData({ label: val }); setLabelText(val); props.onChange?.(val); }; const handleSetEditing = (edit: boolean) => { if (node.data?.lock) { return; } node.setData({ ignoreDrag: edit }); if (edit) { // 置顶 node.toFront(); setTimeout(() => { inputRef.current?.focus({ cursor: "all" }); }, 100); } else { // 更新数据 node.prop("changeNodeData", { cellId: node.id, data: { label: labelText }, ignoreRender: false, }); } setIsEditing(edit); }; const [findObj, setFindObj] = useState<{ findStr: string; currentCellId?: string; currentIndex: number; }>(); // 查找 const handleFind = (args: any) => { setFindObj(args?.current || {}); }; const label = useMemo(() => { if (!findObj) return value; const list = (value || "").split(findObj.findStr || ""); return list.map((str: string, index) => { // 当前的节点展示 const style = findObj.currentCellId === node.id ? { background: index + 1 === findObj.currentIndex ? "#FF9933" : "rgba(255, 153, 51, 0.25)", } : { background: "#ffff00", }; return ( {str} {index < list.length - 1 && ( {findObj.findStr} )} ); }); }, [value, findObj]); const handleReplace = (args: any) => { const { type, searchText, replaceText, currentIndex, currentCellId } = args?.current || {}; // 单个替换 全部替换不在此实现 if(type === 'replace' && currentCellId === node.id) { const list = value.split(searchText); const text = list.map((str, index) => { const result = index + 1 === currentIndex ? replaceText : searchText; return str + (index < list.length - 1 ? result : ''); }).join(""); handleChange(text); } }; const handleClear = () => { setFindObj(undefined); }; useEffect(() => { node.off("change:find", handleFind); node.off("change:replace", handleReplace); node.off("change:clearFind", handleClear); node.off("change:customEdit", handleSetEditing); node.on("change:find", handleFind); node.on("change:replace", handleReplace); node.on("change:clearFind", handleClear); node.on("change:customEdit", handleSetEditing); return () => { node.off("change:find", handleFind); node.off("change:replace", handleReplace); node.off("change:clearFind", handleClear); node.off("change:customEdit", handleSetEditing); }; }, [value]); return (
handleSetEditing(true)} > {label}
{isEditing && ( handleChange(e.target.value)} onBlur={() => handleSetEditing(false)} autoSize /> )}
); }