Z ZPI 文档 v0.3.8
介绍页

源码

packages/ui/src/components/ToolFailure.tsx

tsx55 行查看原文
// Error tooltip presentation follows ZCode ToolCallBlocks/ToolLayout.tsx (Apache-2.0).
import * as Tooltip from "@radix-ui/react-tooltip";
import { Check, Copy } from "lucide-react";
import { useEffect, useRef, useState } from "react";

export function ToolFailure({ text, onCopy }: { text: string; onCopy?: (text: string) => Promise<void> }) {
  const [copied, setCopied] = useState(false);
  const [error, setError] = useState(false);
  const resetCopy = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
  useEffect(() => () => clearTimeout(resetCopy.current), []);
  return (
    <Tooltip.Provider delayDuration={0}>
      <Tooltip.Root>
        <Tooltip.Trigger asChild>
          <span className="tool-failure">执行失败</span>
        </Tooltip.Trigger>
        <Tooltip.Portal>
          <Tooltip.Content
            side="top"
            align="start"
            sideOffset={4}
            collisionPadding={12}
            className="tool-error-tooltip"
          >
            <pre className="tool-error-content">{text}</pre>
            <button
              type="button"
              className="tool-error-copy"
              disabled={!onCopy}
              aria-label={copied ? "已复制错误" : "复制错误详情"}
              title={copied ? "已复制" : "复制错误详情"}
              onClick={async (event) => {
                event.preventDefault();
                event.stopPropagation();
                try {
                  await onCopy?.(text);
                  setCopied(true);
                  setError(false);
                  clearTimeout(resetCopy.current);
                  resetCopy.current = setTimeout(() => setCopied(false), 1500);
                } catch {
                  setError(true);
                }
              }}
            >
              {copied ? <Check size={12} /> : <Copy size={12} />}
            </button>
            {error && <small role="alert">复制失败,请重试</small>}
          </Tooltip.Content>
        </Tooltip.Portal>
      </Tooltip.Root>
    </Tooltip.Provider>
  );
}