修复
This commit is contained in:
176
src/App.tsx
176
src/App.tsx
@@ -25,6 +25,7 @@ import { exportLabelsPdfAsync, type PdfExportProgress } from './pdfExport';
|
||||
import { useIsMobile } from './hooks/useIsMobile';
|
||||
import { useUndoRedo } from './hooks/useUndoRedo';
|
||||
import { useAppDialog } from './components/AppDialog';
|
||||
import { AnchoredMenu } from './components/AnchoredMenu';
|
||||
import {
|
||||
FileDown,
|
||||
Code,
|
||||
@@ -153,7 +154,7 @@ export default function App() {
|
||||
const [editingTemplateId, setEditingTemplateId] = useState<string | null>(null);
|
||||
const [editTmplName, setEditTmplName] = useState<string>('');
|
||||
const [templateMenuId, setTemplateMenuId] = useState<string | null>(null);
|
||||
const templateMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
const templateMenuAnchorRef = useRef<HTMLDivElement | null>(null);
|
||||
const [headerTemplateMenuOpen, setHeaderTemplateMenuOpen] = useState(false);
|
||||
const headerTemplateMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
const importTemplateInputRef = useRef<HTMLInputElement | null>(null);
|
||||
@@ -390,26 +391,6 @@ export default function App() {
|
||||
|
||||
const closeTemplateMenu = () => setTemplateMenuId(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!templateMenuId) return;
|
||||
const handlePointerDown = (e: PointerEvent) => {
|
||||
if (templateMenuRef.current?.contains(e.target as Node)) return;
|
||||
closeTemplateMenu();
|
||||
};
|
||||
document.addEventListener('pointerdown', handlePointerDown);
|
||||
return () => document.removeEventListener('pointerdown', handlePointerDown);
|
||||
}, [templateMenuId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!headerTemplateMenuOpen) return;
|
||||
const handlePointerDown = (e: PointerEvent) => {
|
||||
if (headerTemplateMenuRef.current?.contains(e.target as Node)) return;
|
||||
setHeaderTemplateMenuOpen(false);
|
||||
};
|
||||
document.addEventListener('pointerdown', handlePointerDown);
|
||||
return () => document.removeEventListener('pointerdown', handlePointerDown);
|
||||
}, [headerTemplateMenuOpen]);
|
||||
|
||||
const handleEditTemplateSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!editingTemplateId) return;
|
||||
@@ -841,37 +822,37 @@ export default function App() {
|
||||
>
|
||||
<MoreHorizontal className="w-5 h-5 shrink-0" />
|
||||
</button>
|
||||
{headerTemplateMenuOpen && (
|
||||
<div
|
||||
role="menu"
|
||||
className="absolute right-0 top-full mt-1 z-30 min-w-[148px] py-1 bg-white border border-gray-200 rounded-xl shadow-lg"
|
||||
<AnchoredMenu
|
||||
open={headerTemplateMenuOpen}
|
||||
onClose={() => setHeaderTemplateMenuOpen(false)}
|
||||
anchorRef={headerTemplateMenuRef}
|
||||
className="min-w-[148px] py-1 bg-white border border-gray-200 rounded-xl shadow-lg"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
setHeaderTemplateMenuOpen(false);
|
||||
setShowAddTmplForm(true);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
setHeaderTemplateMenuOpen(false);
|
||||
setShowAddTmplForm(true);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<Plus className="w-4 h-4 shrink-0" />
|
||||
新建模板
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
setHeaderTemplateMenuOpen(false);
|
||||
importTemplateInputRef.current?.click();
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<Upload className="w-4 h-4 shrink-0" />
|
||||
导入模板
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<Plus className="w-4 h-4 shrink-0" />
|
||||
新建模板
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
setHeaderTemplateMenuOpen(false);
|
||||
importTemplateInputRef.current?.click();
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<Upload className="w-4 h-4 shrink-0" />
|
||||
导入模板
|
||||
</button>
|
||||
</AnchoredMenu>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
@@ -1067,7 +1048,7 @@ export default function App() {
|
||||
{isMobile ? '生成' : '排版导出'}
|
||||
</button>
|
||||
<div
|
||||
ref={templateMenuId === tmpl.id ? templateMenuRef : null}
|
||||
ref={templateMenuId === tmpl.id ? templateMenuAnchorRef : null}
|
||||
className="relative shrink-0"
|
||||
>
|
||||
<button
|
||||
@@ -1085,53 +1066,52 @@ export default function App() {
|
||||
>
|
||||
<MoreHorizontal className={`${isMobile ? 'w-5 h-5' : 'w-4 h-4'} shrink-0`} />
|
||||
</button>
|
||||
{templateMenuId === tmpl.id && (
|
||||
<div
|
||||
role="menu"
|
||||
className="absolute right-0 top-full mt-1 z-30 min-w-[90px] py-1 bg-white border border-gray-200 rounded-xl shadow-lg"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
<AnchoredMenu
|
||||
open={templateMenuId === tmpl.id}
|
||||
onClose={closeTemplateMenu}
|
||||
anchorRef={templateMenuAnchorRef}
|
||||
className="min-w-[120px] py-1 bg-white border border-gray-200 rounded-xl shadow-lg"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeTemplateMenu();
|
||||
openEditTemplateDialog(tmpl);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeTemplateMenu();
|
||||
openEditTemplateDialog(tmpl);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<Pencil className="w-4 h-4 shrink-0" />
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeTemplateMenu();
|
||||
handleExportTemplate(tmpl);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<FileDown className="w-4 h-4 shrink-0" />
|
||||
导出
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeTemplateMenu();
|
||||
void handleDeleteTemplate(tmpl.id!);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-rose-600 hover:bg-rose-50 active:bg-rose-100 cursor-pointer"
|
||||
>
|
||||
<Trash2 className="w-4 h-4 shrink-0" />
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<Pencil className="w-4 h-4 shrink-0" />
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeTemplateMenu();
|
||||
handleExportTemplate(tmpl);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-gray-700 hover:bg-gray-50 active:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<FileDown className="w-4 h-4 shrink-0" />
|
||||
导出
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="menuitem"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeTemplateMenu();
|
||||
void handleDeleteTemplate(tmpl.id!);
|
||||
}}
|
||||
className="inline-flex items-center gap-3 w-full px-3 py-2.5 text-left text-sm text-rose-600 hover:bg-rose-50 active:bg-rose-100 cursor-pointer"
|
||||
>
|
||||
<Trash2 className="w-4 h-4 shrink-0" />
|
||||
删除
|
||||
</button>
|
||||
</AnchoredMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user