Refactor component structure: move ComponentOptions to main.ts, update package.json, and remove unused files

This commit is contained in:
Astrian Zheng 2025-05-14 15:21:45 +10:00
parent 5a1d8469d6
commit cd4d195bd4
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
5 changed files with 69 additions and 43 deletions

View File

@ -1,8 +1,8 @@
{ {
"name": "laterano", "name": "laterano",
"version": "0.0.0", "version": "0.0.0",
"main": "dist/index.js", "main": "dist/main.js",
"types": "dist/index.d.ts", "types": "dist/main.d.ts",
"scripts": { "scripts": {
"build": "tsc" "build": "tsc"
}, },

View File

@ -1,32 +0,0 @@
export default (options: ComponentOptions) => {
const { tag, template, style, onMount, onUnmount, onAttributeChanged } = options
class CustomElement extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot!.innerHTML = `
<style>${style}</style>
${template}
`
}
connectedCallback() {
if (onMount) onMount()
}
disconnectedCallback() {
if (onUnmount) onUnmount()
}
static get observedAttributes() {
return ['data-attribute']
}
attributeChangedCallback(attrName: string, oldValue: string, newValue: string) {
if (onAttributeChanged) onAttributeChanged(attrName, oldValue, newValue)
}
}
customElements.define(tag, CustomElement)
}

66
src/main.ts Normal file
View File

@ -0,0 +1,66 @@
interface ComponentOptions {
tag: string
template: string
style?: string
onMount?: () => void
onUnmount?: () => void
onAttributeChanged?: (attrName: string, oldValue: string, newValue: string) => void
}
export default (options: ComponentOptions) => {
const { tag, template, style, onMount, onUnmount, onAttributeChanged } = options
const componentRegistry = new Map()
componentRegistry.set(tag, options)
const domTree = document.createElement('template')
class CustomElement extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this._initialize()
}
private _initialize() {
if (style) {
const styleElement = document.createElement('style')
styleElement.textContent = style
this.shadowRoot?.appendChild(styleElement)
}
// 使用 text/html 解析,这更适合处理 HTML 模板
const parser = new DOMParser()
const doc = parser.parseFromString(template, 'text/html')
// 找到并导入主要内容元素
const mainContent = doc.body.firstElementChild
if (mainContent) {
// 使用 importNode 确保所有事件和属性都被正确复制
this.shadowRoot?.appendChild(document.importNode(mainContent, true))
} else {
// 如果没有根元素,将所有内容放入一个新的 div 中
const container = document.createElement('div')
container.innerHTML = template
this.shadowRoot?.appendChild(container)
}
}
connectedCallback() {
if (onMount) onMount()
}
disconnectedCallback() {
if (onUnmount) onUnmount()
}
static get observedAttributes() {
return ['data-attribute']
}
attributeChangedCallback(attrName: string, oldValue: string, newValue: string) {
if (onAttributeChanged) onAttributeChanged(attrName, oldValue, newValue)
}
}
customElements.define(tag, CustomElement)
}

View File

@ -1,8 +0,0 @@
interface ComponentOptions {
tag: string
template: string
style?: string
onMount?: () => void
onUnmount?: () => void
onAttributeChanged?: (attrName: string, oldValue: string, newValue: string) => void
}

View File

@ -32,7 +32,7 @@
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
"typeRoots": ["./src/types"], /* Specify multiple folders that act like './node_modules/@types'. */ // "typeRoots": ["./src/types"], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */