123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- import React, { useEffect, useMemo, useRef, useState } from "react";
- import { Input, InputRef } from "antd";
- import { Node } from "@antv/x6";
- import { useSafeState } from "ahooks";
- import FlowExtra from "./FlowExtra";
- export default function CustomInput(props: {
- value: string;
- styles: React.CSSProperties & {
- textVAlign: "top" | "middle" | "bottom";
- bold: boolean;
- italic: boolean;
- };
- node: Node;
- placeholder?: string;
- txtStyle?: React.CSSProperties;
- onChange?: (value: string) => void;
- }) {
- const { value, styles, node, placeholder, txtStyle } = props;
- const [isEditing, setIsEditing] = useSafeState(false);
- const inputRef = useRef<InputRef>(null);
- const style = useMemo(() => {
- const top =
- styles.textVAlign === "top"
- ? 0
- : styles.textVAlign === "middle"
- ? "50%"
- : undefined;
- const bottom = styles.textVAlign === "bottom" ? 0 : undefined;
- return {
- ...styles,
- fontWeight: styles.bold ? "bold" : undefined,
- fontStyle: styles.italic ? "italic" : undefined,
- transform:
- styles.textVAlign === "middle" ? "translateY(-50%)" : undefined,
- minHeight: "12px",
- top,
- bottom,
- };
- }, [styles]);
- const handleChange = (val: string) => {
- node.setData({ label: val });
- props.onChange?.(val);
- };
- 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 (
- <span key={index}>
- {str}
- {index < list.length - 1 && (
- <span style={style}>{findObj.findStr}</span>
- )}
- </span>
- );
- });
- }, [value, findObj]);
- const handleReplace = (args: any) => {
- console.log("替换:", args);
- const { type, searchText, replaceText, currentIndex, currentCellId } = args?.current || {};
- if(args.current?.type === 'replaceAll') {
- handleChange(value.replaceAll(searchText, replaceText));
- }
- 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("");
- console.log(text);
- handleChange(text);
- }
- };
- const handleClear = () => {
- setFindObj(undefined);
- };
- useEffect(() => {
- node.off("change:find", handleFind);
- node.off("change:replace", handleReplace);
- node.off("change:clearFind", handleClear);
- node.on("change:find", handleFind);
- node.on("change:replace", handleReplace);
- node.on("change:clearFind", handleClear);
- return () => {
- node.off("change:find", handleFind);
- node.off("change:replace", handleReplace);
- node.off("change:clearFind", handleClear);
- };
- }, [value]);
- const handleSetEditing = (edit: boolean) => {
- if (node.data?.lock) {
- return;
- }
- node.setData({
- ignoreDrag: edit,
- });
- if (edit) {
- setTimeout(() => {
- inputRef.current?.focus({ cursor: "all" });
- }, 100);
- }
- setIsEditing(edit);
- };
- // useEffect(() => {
- // // 处理字体加载
- // // @ts-ignore
- // // WebFont.load({
- // // google: {
- // // families: [styles.fontFamily]
- // // }
- // // })
- // }, [styles.fontFamily]);
- return (
- <div className="absolute w-full h-full w-full" style={txtStyle}>
- <FlowExtra node={node} />
- {isEditing ? (
- <Input.TextArea
- ref={inputRef}
- placeholder={placeholder}
- value={value}
- variant="borderless"
- className="absolute"
- style={style}
- onChange={(e) => handleChange(e.target.value)}
- onBlur={() => handleSetEditing(false)}
- autoSize
- />
- ) : (
- <div
- className="absolute w-full"
- style={style}
- onDoubleClick={() => handleSetEditing(true)}
- >
- {label}
- </div>
- )}
- </div>
- );
- }
|