From c071cad50a4f0786f6337629320c89fcca68a894 Mon Sep 17 00:00:00 2001 From: hyper Date: Thu, 9 Jul 2026 16:03:41 +0800 Subject: [PATCH] refactor: Reformat code and update z-index class Reformat md-table.tsx to use double quotes and consistent code style. Change z-index class in PrintPreview from `z-[60]` to `z-60`. --- src/components/md-deck/PrintPreview.tsx | 2 +- src/components/md-table.tsx | 375 +++++++++++++----------- 2 files changed, 202 insertions(+), 175 deletions(-) diff --git a/src/components/md-deck/PrintPreview.tsx b/src/components/md-deck/PrintPreview.tsx index 1d1fd6d..a4e8df5 100644 --- a/src/components/md-deck/PrintPreview.tsx +++ b/src/components/md-deck/PrintPreview.tsx @@ -115,7 +115,7 @@ export function PrintPreview(props: PrintPreviewProps) { } > -
+
{ - noShadowDOM(); - const [rows, setRows] = createSignal>([] as unknown as CSV); - const [activeTab, setActiveTab] = createSignal(0); - const [activeGroup, setActiveGroup] = createSignal(null); - const [bodyHtml, setBodyHtml] = createSignal(''); - let tabsContainer: HTMLDivElement | undefined; +customElement( + "md-table", + { roll: false, remix: false }, + (props, { element }) => { + noShadowDOM(); + const [rows, setRows] = createSignal>( + [] as unknown as CSV, + ); + const [activeTab, setActiveTab] = createSignal(0); + const [activeGroup, setActiveGroup] = createSignal(null); + const [bodyHtml, setBodyHtml] = createSignal(""); + let tabsContainer: HTMLDivElement | undefined; - // 从 element 的 textContent 获取 CSV 路径或 inline CSV 数据 - const rawContent = element?.textContent?.trim() || ''; + // 从 element 的 textContent 获取 CSV 路径或 inline CSV 数据 + const rawContent = element?.textContent?.trim() || ""; - // 隐藏原始文本内容 - if (element) { - element.textContent = ''; - } - - // 从父节点 article 的 data-src 获取当前 markdown 文件完整路径 - const articleEl = element?.closest('article[data-src]'); - const articlePath = articleEl?.getAttribute('data-src') || ''; - - // 如果是 inline CSV,直接使用;否则解析相对路径 - const contentOrPath = isCSV(rawContent) ? rawContent : resolvePath(articlePath, rawContent); - - // 使用 createResource 加载 CSV,自动响应路径变化并避免重复加载 - const [csvData] = createResource(() => contentOrPath, loadCSV); - - // 当数据加载完成后更新 rows - createEffect(() => { - const data = csvData(); - if (data) { - // 将加载的数据赋值给 rows,CSV 类型已经包含 sourcePath 等属性 - setRows(data as unknown as CSV); + // 隐藏原始文本内容 + if (element) { + element.textContent = ""; } - }); - // 检测是否有 group 列 - const hasGroup = createMemo(() => { - const allRows = rows(); - return allRows.length > 0 && 'group' in allRows[0]; - }); + // 从父节点 article 的 data-src 获取当前 markdown 文件完整路径 + const articleEl = element?.closest("article[data-src]"); + const articlePath = articleEl?.getAttribute("data-src") || ""; - // 获取所有分组 - const groups = createMemo(() => { - if (!hasGroup()) return []; - const allRows = rows(); - const groupSet = new Set(); - for (const row of allRows) { - if (row.group) { - groupSet.add(row.group); + // 如果是 inline CSV,直接使用;否则解析相对路径 + const contentOrPath = isCSV(rawContent) + ? rawContent + : resolvePath(articlePath, rawContent); + + // 使用 createResource 加载 CSV,自动响应路径变化并避免重复加载 + const [csvData] = createResource(() => contentOrPath, loadCSV); + + // 当数据加载完成后更新 rows + createEffect(() => { + const data = csvData(); + if (data) { + // 将加载的数据赋值给 rows,CSV 类型已经包含 sourcePath 等属性 + setRows(data as unknown as CSV); } - } - return Array.from(groupSet).sort(); - }); + }); - // 根据当前选中的分组过滤行 - const filteredRows = createMemo(() => { - const allRows = rows(); - const group = activeGroup(); - if (!group) return allRows; - return allRows.filter(row => row.group === group); - }); + // 检测是否有 group 列 + const hasGroup = createMemo(() => { + const allRows = rows(); + return allRows.length > 0 && "group" in allRows[0]; + }); - // 处理 body 内容中的 {{prop}} 语法并解析 markdown - const processBody = (body: string, currentRow: TableRow): string => { - // 使用 marked 解析 markdown - return marked.parse(processVariables(body, currentRow, rows(), filteredRows(), props.remix)) as string; - }; + // 获取所有分组 + const groups = createMemo(() => { + if (!hasGroup()) return []; + const allRows = rows(); + const groupSet = new Set(); + for (const row of allRows) { + if (row.group) { + groupSet.add(row.group); + } + } + return Array.from(groupSet).sort(); + }); - // 更新 body 内容 - const updateBodyContent = () => { - const filtered = filteredRows(); - if (!csvData.loading && filtered.length > 0) { - const index = Math.min(activeTab(), filtered.length - 1); - const currentRow = filtered[index]; - setBodyHtml(processBody(currentRow.body, currentRow)); - } - }; + // 根据当前选中的分组过滤行 + const filteredRows = createMemo(() => { + const allRows = rows(); + const group = activeGroup(); + if (!group) return allRows; + return allRows.filter((row) => row.group === group); + }); - // 监听 activeTab 和 activeGroup 变化并更新内容 - createEffect(() => { - activeTab(); - activeGroup(); - updateBodyContent(); - }); + // 处理 body 内容中的 {{prop}} 语法并解析 markdown + const processBody = (body: string, currentRow: TableRow): string => { + // 使用 marked 解析 markdown + return marked.parse( + processVariables(body, currentRow, rows(), filteredRows(), props.remix), + ) as string; + }; - // 切换分组时重置 tab 索引 - const handleGroupChange = (group: string | null) => { - setActiveGroup(group); - setActiveTab(0); - }; + // 更新 body 内容 + const updateBodyContent = () => { + const filtered = filteredRows(); + if (!csvData.loading && filtered.length > 0) { + const index = Math.min(activeTab(), filtered.length - 1); + const currentRow = filtered[index]; + setBodyHtml(processBody(currentRow.body, currentRow)); + } + }; - // 随机切换 tab - const handleRoll = () => { - const filtered = filteredRows(); - if (filtered.length === 0) return; - - // 检查所有 label 是否都是整数/整数范围格式 - const labels = filtered.map(row => row.label); - if (areAllLabelsNumeric(labels)) { - // 使用加权随机 - const randomIndex = weightedRandomIndex(labels); - if (randomIndex !== -1) { + // 监听 activeTab 和 activeGroup 变化并更新内容 + createEffect(() => { + activeTab(); + activeGroup(); + updateBodyContent(); + }); + + // 切换分组时重置 tab 索引 + const handleGroupChange = (group: string | null) => { + setActiveGroup(group); + setActiveTab(0); + }; + + // 随机切换 tab + const handleRoll = () => { + const filtered = filteredRows(); + if (filtered.length === 0) return; + + // 检查所有 label 是否都是整数/整数范围格式 + const labels = filtered.map((row) => row.label); + if (areAllLabelsNumeric(labels)) { + // 使用加权随机 + const randomIndex = weightedRandomIndex(labels); + if (randomIndex !== -1) { + setActiveTab(randomIndex); + } + } else { + // 使用简单随机 + const randomIndex = Math.floor(Math.random() * filtered.length); setActiveTab(randomIndex); } - } else { - // 使用简单随机 - const randomIndex = Math.floor(Math.random() * filtered.length); - setActiveTab(randomIndex); - } - - // 滚动到可视区域 - setTimeout(() => { - const activeButton = tabsContainer?.querySelector('.border-blue-600'); - activeButton?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }); - }, 50); - }; - return ( -
-
-
- {/* 分组 tabs */} - -
- - - {(group) => ( - - )} - -
-
- {/* 内容 tabs */} -
- - + // 滚动到可视区域 + setTimeout(() => { + const activeButton = tabsContainer?.querySelector(".border-blue-600"); + activeButton?.scrollIntoView({ + behavior: "smooth", + block: "nearest", + inline: "nearest", + }); + }, 50); + }; + + return ( +
+
+
+ {/* 分组 tabs */} + +
+ + + {(group) => ( + + )} + +
-
- - {(row, index) => ( - - )} - + {/* 内容 tabs */} +
+ + + +
+ + {(row, index) => ( + + )} + +
+
+ 0}> +
+ +
-
- 0}> -
- -
-
- ); -}); + ); + }, +);