({
id,
index,
config,
currentVal,
inlineDefault = null, // 当前位置的内联值(来自 {{A: val}} 语法)
temporaryInlineVals = [], // 本模版下该变量所有临时词条(不在词库中),跨位置收集
isOpen,
onToggle,
onSelect,
onAddCustom,
popoverRef,
categories,
t,
language,
isDarkMode,
groupId = null, // 新增:分组ID,用于显示分组标识
// AI 相关 props(预留接口)
onGenerateAITerms = null, // AI 生成词条的回调函数
templateContext = "", // 新增:模版全文内容
})
| 17 | } from '../constants/aiConfig'; |
| 18 | |
| 19 | export const Variable = ({ |
| 20 | id, |
| 21 | index, |
| 22 | config, |
| 23 | currentVal, |
| 24 | inlineDefault = null, // 当前位置的内联值(来自 {{A: val}} 语法) |
| 25 | temporaryInlineVals = [], // 本模版下该变量所有临时词条(不在词库中),跨位置收集 |
| 26 | isOpen, |
| 27 | onToggle, |
| 28 | onSelect, |
| 29 | onAddCustom, |
| 30 | popoverRef, |
| 31 | categories, |
| 32 | t, |
| 33 | language, |
| 34 | isDarkMode, |
| 35 | groupId = null, // 新增:分组ID,用于显示分组标识 |
| 36 | // AI 相关 props(预留接口) |
| 37 | onGenerateAITerms = null, // AI 生成词条的回调函数 |
| 38 | templateContext = "", // 新增:模版全文内容 |
| 39 | }) => { |
| 40 | const [isAdding, setIsAdding] = useState(false); |
| 41 | const [newOptionPrimary, setNewOptionPrimary] = useState(""); |
| 42 | const [newOptionSecondary, setNewOptionSecondary] = useState(""); |
| 43 | const [isHovered, setIsHovered] = useState(false); |
| 44 | const [alignRight, setAlignRight] = useState(false); |
| 45 | const [alignTop, setAlignTop] = useState(false); |
| 46 | const [maxPopoverWidth, setMaxPopoverWidth] = useState('95vw'); |
| 47 | const [popoverPos, setPopoverPos] = useState(null); |
| 48 | |
| 49 | // 核心优化:改用即时检测,确保渲染初期定位逻辑正确 |
| 50 | // 增加阈值到 1024px,确保在平板和窄屏下也能触发居中模态框模式 |
| 51 | const [isMobileDevice, setIsMobileDevice] = useState(typeof window !== 'undefined' && window.innerWidth < 1024); |
| 52 | const containerRef = useRef(null); |
| 53 | |
| 54 | // 初始化移动端检测 |
| 55 | useEffect(() => { |
| 56 | const checkMobile = () => setIsMobileDevice(window.innerWidth < 1024); |
| 57 | checkMobile(); |
| 58 | window.addEventListener('resize', checkMobile); |
| 59 | return () => window.removeEventListener('resize', checkMobile); |
| 60 | }, []); |
| 61 | |
| 62 | // AI 相关状态 |
| 63 | const [aiTerms, setAiTerms] = useState([]); // AI 生成的词条 |
| 64 | const [isAILoading, setIsAILoading] = useState(false); // AI 加载状态 |
| 65 | const [aiError, setAiError] = useState(null); // AI 错误信息 |
| 66 | const [visibleAiTermsCount, setVisibleAiTermsCount] = useState(0); // 新增:可见的 AI 词条数量,用于逐个显示效果 |
| 67 | const [hasGeneratedOnce, setHasGeneratedOnce] = useState(false); // 新增:是否已经生成过词条 |
| 68 | |
| 69 | //文字渐变色 |
| 70 | const TEXT_GRADIENT = 'linear-gradient(90deg, #F77F56 0%, rgba(255, 71, 20, 0.97) 100%)'; |
| 71 | |
| 72 | // Determine styles based on category |
| 73 | const categoryId = config?.category || 'other'; |
| 74 | const colorKey = categories[categoryId]?.color || 'slate'; |
| 75 | const style = CATEGORY_STYLES[colorKey] || CATEGORY_STYLES.slate; |
| 76 | const premium = PREMIUM_STYLES[colorKey] || PREMIUM_STYLES.slate; |
nothing calls this directly
no test coverage detected