import React, { useState, useEffect, useMemo } from 'react'; import { LabelTemplate, TemplateElement, PaperConfig, VisibilityRule } from '../types'; import { extractTemplateVariables, extractVariablesFromContent, isConditionalVisibility, isTemplateVariableInUse, removeUnusedTemplateVariable, resolveVisibilityRules, } from '../utils'; import { VisibilityRuleDialog } from './VisibilityRuleDialog'; import { VisibilityRuleSummary } from './VisibilityRuleSummary'; import { alignToSelectionBounds, alignSelectionToCanvas, tileSelectedEvenly, type AlignMode, } from '../elementAlign'; import { CollapsiblePanelSection } from './CollapsiblePanelSection'; import { CommitInput } from './CommitInput'; import { Sliders, LayoutGrid, Type, AlignLeft, AlignCenter, AlignRight, Bold, Italic, Underline, Strikethrough, HelpCircle, Lock, Unlock, ArrowUp, ArrowDown, Layers, Trash2, AlignHorizontalJustifyStart, AlignHorizontalJustifyCenter, AlignHorizontalJustifyEnd, AlignVerticalJustifyStart, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignHorizontalSpaceBetween, AlignVerticalSpaceBetween, Link2, Plus, Ruler, RotateCw, Barcode, QrCode, Image as ImageIcon, Upload, } from 'lucide-react'; const PANEL_COLLAPSE_STORAGE_KEY = 'label_designer_panel_collapse_v2'; type PanelCollapseState = { content: boolean; properties: boolean; layers: boolean; }; function loadPanelCollapseState(): PanelCollapseState { try { const raw = localStorage.getItem(PANEL_COLLAPSE_STORAGE_KEY); if (raw) return JSON.parse(raw) as PanelCollapseState; } catch { /* ignore */ } return { content: true, properties: false, layers: true }; } const alignBtnClass = 'px-2 py-1.5 bg-[#383838] hover:bg-[#444] border border-[#4a4a4a] hover:border-[#31a8ff]/50 text-[10px] text-[#ccc] flex flex-col items-center justify-center gap-0.5 transition cursor-pointer rounded-sm min-h-[52px]'; interface AlignToolButtonProps { icon: React.ReactNode; label: string; title: string; onClick: () => void; } const AlignToolButton: React.FC = ({ icon, label, title, onClick }) => ( ); const PropInput = CommitInput; interface PropTextareaProps extends Omit, 'onChange'> { value: string; onCommit: (val: string) => void; } const PropTextarea: React.FC = ({ value, onCommit, ...props }) => { const [localVal, setLocalVal] = useState(value); useEffect(() => { setLocalVal(value); }, [value]); const handleBlur = () => { if (localVal !== value) { onCommit(localVal); } }; return (