From 795c2c4389a3a86b7327ef52d9476b6ac2efff68 Mon Sep 17 00:00:00 2001 From: hypercross Date: Thu, 26 Feb 2026 00:47:26 +0800 Subject: [PATCH] fix: solid-element --- package-lock.json | 19 +++++++++++++++++++ package.json | 1 + src/App.tsx | 3 +++ src/components/dice.tsx | 24 ++++++++++++------------ src/components/index.ts | 9 ++++++--- src/components/table.tsx | 32 +++++++++++++++++++++----------- src/markdown/index.ts | 2 +- 7 files changed, 63 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index fbc05ee..d5999fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "csv-parse": "^5.5.6", "marked": "^14.1.0", "marked-directive": "^1.0.7", + "solid-element": "^1.9.1", "solid-js": "^1.9.3" }, "bin": { @@ -2356,6 +2357,12 @@ "node": ">=18" } }, + "node_modules/component-register": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/component-register/-/component-register-0.8.8.tgz", + "integrity": "sha512-djhwcxjY+X9dacaYUEOkOm7tda8uOEDiMDigWysu3xv54M8o6XDlsjR1qt5Y8QLGiKg51fqXFIR2HUTmt9ys0Q==", + "license": "MIT" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3167,6 +3174,18 @@ "seroval": "^1.0" } }, + "node_modules/solid-element": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/solid-element/-/solid-element-1.9.1.tgz", + "integrity": "sha512-baJy6Qz27oAUgkPlqOf3Y+7RsBiuVQrS51Nrh1ddDbrqrNPvJbIvehpUsTzLNFb2ZHIoHuNnDg330go/ZKcRdg==", + "license": "MIT", + "dependencies": { + "component-register": "^0.8.7" + }, + "peerDependencies": { + "solid-js": "^1.9.3" + } + }, "node_modules/solid-js": { "version": "1.9.11", "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.11.tgz", diff --git a/package.json b/package.json index 1e04124..02233ee 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "csv-parse": "^5.5.6", "marked": "^14.1.0", "marked-directive": "^1.0.7", + "solid-element": "^1.9.1", "solid-js": "^1.9.3" }, "devDependencies": { diff --git a/src/App.tsx b/src/App.tsx index 559a2a1..d0ff792 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,9 @@ import { Component, createSignal, onMount } from 'solid-js'; import { useLocation } from '@solidjs/router'; import { parseMarkdown } from './markdown'; +// 导入组件以注册自定义元素 +import './components'; + const App: Component = () => { const location = useLocation(); const [content, setContent] = createSignal(''); diff --git a/src/components/dice.tsx b/src/components/dice.tsx index 3520aa8..68acb90 100644 --- a/src/components/dice.tsx +++ b/src/components/dice.tsx @@ -1,9 +1,5 @@ -import { Component, createSignal, Show } from 'solid-js'; - -export interface DiceProps { - formula: string; - key?: string; -} +import { customElement, noShadowDOM } from 'solid-element'; +import { createSignal } from 'solid-js'; function rollDice(formula: string): number { // 解析骰子公式,例如:2d6+d8 @@ -30,10 +26,14 @@ function rollDice(formula: string): number { return total; } -export const Dice: Component = (props) => { +customElement('ttrpg-dice', { key: '' }, (props, { element }) => { + noShadowDOM(); const [result, setResult] = createSignal(null); const [isRolled, setIsRolled] = createSignal(false); + // 从 element 的 textContent 获取骰子公式 + const formula = element?.textContent?.trim() || ''; + const handleClick = () => { if (isRolled()) { // 重置为公式 @@ -41,18 +41,17 @@ export const Dice: Component = (props) => { setIsRolled(false); } else { // 掷骰子 - const rollResult = rollDice(props.formula); + const rollResult = rollDice(formula); setResult(rollResult); setIsRolled(true); } }; - const displayText = () => (isRolled() ? `${result()}` : props.formula); - const queryParams = () => (props.key && isRolled() ? `?dice-${props.key}=${result()}` : ''); + const displayText = () => (isRolled() ? `${result()}` : formula); return ( { e.preventDefault(); handleClick(); @@ -63,4 +62,5 @@ export const Dice: Component = (props) => { {displayText()} ); -}; +}); + diff --git a/src/components/index.ts b/src/components/index.ts index a884e8f..f12a7aa 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,5 +1,8 @@ -export { Dice } from './dice'; -export type { DiceProps } from './dice'; +// 导入以注册自定义元素 +import './dice'; +import './table'; -export { Table } from './table'; +// 导出类型 +export type { DiceProps } from './dice'; export type { TableProps } from './table'; + diff --git a/src/components/table.tsx b/src/components/table.tsx index 210a73c..cda4004 100644 --- a/src/components/table.tsx +++ b/src/components/table.tsx @@ -1,21 +1,18 @@ -import { Component, createSignal, For, Show } from 'solid-js'; +import { customElement, noShadowDOM } from 'solid-element'; +import { createSignal, For, Show } from 'solid-js'; import { parse } from 'csv-parse/sync'; -export interface TableProps { - src: string; - roll?: boolean; - remix?: boolean; -} - interface TableRow { label: string; body: string; [key: string]: string; } -export const Table: Component = (props) => { +customElement('ttrpg-table', { src: '', roll: false, remix: false }, (props, { element }) => { + noShadowDOM(); const [rows, setRows] = createSignal([]); const [activeTab, setActiveTab] = createSignal(0); + const [loaded, setLoaded] = createSignal(false); // 解析 CSV 内容 const parseCSV = (content: string) => { @@ -24,6 +21,7 @@ export const Table: Component = (props) => { skip_empty_lines: true, }); setRows(records as TableRow[]); + setLoaded(true); }; // 加载 CSV 文件 @@ -34,11 +32,14 @@ export const Table: Component = (props) => { parseCSV(content); } catch (error) { console.error('Failed to load CSV:', error); + setLoaded(true); } }; // 初始化加载 - loadCSV(); + if (!loaded()) { + loadCSV(); + } // 随机切换 tab const handleRoll = () => { @@ -80,12 +81,21 @@ export const Table: Component = (props) => { )} + + +
- 0}> + 0}>
); -}; +}); diff --git a/src/markdown/index.ts b/src/markdown/index.ts index a96a4e2..3b69d02 100644 --- a/src/markdown/index.ts +++ b/src/markdown/index.ts @@ -1,7 +1,7 @@ import { Marked } from 'marked'; import { createDirectives } from 'marked-directive'; -// 使用 marked-directive 来支持通过 @solidjs/element 添加的 UI 组件 +// 使用 marked-directive 来支持指令语法 const marked = new Marked().use(createDirectives()); export function parseMarkdown(content: string): string {