import { customElement, noShadowDOM } from "solid-element"; import { Show, onCleanup } from "solid-js"; import { resolvePath } from "../utils/path"; import { v4 as uuidv4 } from "uuid"; import { createDeckStore } from "./hooks/deckStore"; import { registerDeck, unregisterDeck } from "./hooks/deck-registry"; import type { CardShape } from "./types"; import { DeckHeader } from "./DeckHeader"; import { CardList } from "./CardList"; import { DeckContent } from "./DeckContent"; import { EditorTabs } from "./EditorTabs"; import { PrintPreview } from "./PrintPreview"; import { DataEditorPanel } from "./editor-panel"; interface DeckProps { size?: string; sizeW?: number; sizeH?: number; grid?: string; gridW?: number; gridH?: number; bleed?: number | string; padding?: number | string; shape?: CardShape; layers?: string; backLayers?: string; fixed?: boolean | string; } customElement( "md-deck", { size: "", sizeW: 54, sizeH: 86, grid: "", gridW: 5, gridH: 8, bleed: 1, padding: 2, shape: "rectangle", layers: "", backLayers: "", fixed: false, }, (props, { element }) => { noShadowDOM(); // 从 element 的 textContent 获取 CSV 路径 const csvPath = element?.textContent?.trim() || ""; // 隐藏原始文本内容 if (element) { element.textContent = ""; } // 从父节点 article 的 data-src 获取当前 markdown 文件完整路径 const articleEl = element?.closest("article[data-src]"); const articlePath = articleEl?.getAttribute("data-src") || ""; // 解析相对路径 const resolvedSrc = resolvePath(articlePath, csvPath); // 创建 store 并加载数据 const store = createDeckStore(resolvedSrc); // 生成唯一 ID 并注册到全局注册表 const deckId = `deck-${uuidv4()}`; registerDeck(deckId, store, resolvedSrc, csvPath); // 解析 size 属性(支持旧格式 "54x86" 和新格式) if (props.size && props.size.includes("x")) { const [w, h] = props.size.split("x").map(Number); store.actions.setSizeW(w); store.actions.setSizeH(h); } else { store.actions.setSizeW(props.sizeW ?? 54); store.actions.setSizeH(props.sizeH ?? 86); } // 解析 grid 属性(支持旧格式 "5x8" 和新格式) if (props.grid && props.grid.includes("x")) { const [w, h] = props.grid.split("x").map(Number); store.actions.setGridW(w); store.actions.setGridH(h); } else { store.actions.setGridW(props.gridW ?? 5); store.actions.setGridH(props.gridH ?? 8); } // 解析 bleed 和 padding(支持旧字符串格式和新数字格式) if (typeof props.bleed === "string") { store.actions.setBleed(Number(props.bleed)); } else { store.actions.setBleed(props.bleed ?? 1); } if (typeof props.padding === "string") { store.actions.setPadding(Number(props.padding)); } else { store.actions.setPadding(props.padding ?? 2); } // 设置形状 store.actions.setShape(props.shape ?? "rectangle"); // 加载 CSV 数据 store.actions.loadCardsFromPath( resolvedSrc, csvPath, (props.layers as string) || "", (props.backLayers as string) || "", ); // 清理函数 onCleanup(() => { unregisterDeck(deckId); store.actions.clearError(); }); return (
{/* 导出 PDF 预览弹窗 */} store.actions.setExporting(false)} onExport={() => {}} /> {/* Tab 选择器和编辑按钮 */} 0 && !store.state.error}>
{/* 左侧:卡牌列表导航 */} 0 && !store.state.error}> {/* 中间:内容区域(错误/加载/卡牌预览/空状态) */}
{/* 右侧:属性/图层编辑面板(标签页切换) */}
); }, );