feat: 静态类中的函数继承范性

model onClose and ondestory函数
createDOMElemnet 从jsx
This commit is contained in:
2024-09-21 17:40:53 +08:00
parent e2c0f80f04
commit 1fbf1b64d9
14 changed files with 1778 additions and 44 deletions

View File

@@ -0,0 +1,79 @@
export function createDOMElement(jsxElement: JSX.Element) {
// 如果 jsxElement 是 null, undefined 或者是布尔值,则直接跳过处理
if (jsxElement == null || typeof jsxElement === 'boolean') {
console.warn('Invalid JSX element:', jsxElement);
return null;
}
const { type, props } = jsxElement;
// React Fragment 的处理
if (type === Symbol.for('react.fragment')) {
const fragment = document.createDocumentFragment();
if (props.children) {
if (Array.isArray(props.children)) {
props.children.forEach((child) => {
const childElement = createDOMElement(child);
if (childElement) {
fragment.appendChild(childElement);
}
});
} else {
const childElement = createDOMElement(props.children);
if (childElement) {
fragment.appendChild(childElement);
}
}
}
return fragment;
}
const domElement = document.createElement(type);
// 处理 props
Object.keys(props).forEach((prop) => {
if (prop === 'children') {
// 递归处理 children
if (Array.isArray(props.children)) {
props.children.forEach((child) => {
const childElement = createDOMElement(child);
if (childElement) {
domElement.appendChild(childElement);
}
});
} else if (typeof props.children === 'string') {
domElement.appendChild(document.createTextNode(props.children));
} else if (typeof props.children === 'object' && props.children !== null) {
const childElement = createDOMElement(props.children);
if (childElement) {
domElement.appendChild(childElement);
}
}
} else if (prop.startsWith('on')) {
// 处理事件监听器
const eventType = prop.slice(2).toLowerCase(); // 提取事件类型(如 onClick -> click
domElement.addEventListener(eventType, props[prop]);
} else if (prop === 'style' && typeof props[prop] === 'object') {
// 处理 style 属性
Object.assign(domElement.style, props[prop]);
} else if (prop === 'dangerouslySetInnerHTML') {
// 处理 dangerouslySetInnerHTML
if (props[prop] && typeof props[prop].__html === 'string') {
domElement.innerHTML = props[prop].__html;
} else {
console.warn('Invalid dangerouslySetInnerHTML content:', props[prop]);
}
} else if (prop === 'ref') {
// React 的 ref 在手动创建 DOM 时没有用处
console.warn('Ref prop is not supported in manual DOM creation');
} else if (prop === 'key') {
// React 的 key 属性是用于虚拟 DOM 的,不影响实际 DOM
console.warn('Key prop is not applicable in manual DOM creation');
} else {
// 处理其他普通属性
domElement.setAttribute(prop, props[prop]);
}
});
return domElement;
}

View File

@@ -1,7 +1,9 @@
import { modalStore, Modal, DialogModal } from '@kevisual/ui';
import { calc } from 'antd/es/theme/internal';
import { DialogModal, Modal, modalStore } from '@kevisual/ui';
import { useEffect, useRef } from 'react';
import '@kevisual/ui/src/index.css';
import { createDOMElement } from './create-dom';
// import '@kevisual/ui/src/components/modal/index.css';
export const App = () => {
const showModel = () => {
//
@@ -17,6 +19,8 @@ export const App = () => {
}}>
<ModelOne />
<ModelTwo />
<ModelTwo2 />
<ModelThree />
</div>
</div>
);
@@ -29,7 +33,7 @@ const ModelOne = () => {
};
return (
<div>
<div className='w-100 h-100 p-4 rounded-md shadow-md bg-slate-200'>
<div className='w-96 p-4 rounded-md shadow-md bg-slate-200'>
model one
<div className='cursor-pointer p-2 border' onClick={showModel}>
show
@@ -50,12 +54,12 @@ const ModelTwo = () => {
contentStyle: {
// maxHeight: '100px',
// overflow: 'auto',
}
},
});
};
return (
<div>
<div className='w-100 h-100 p-4 rounded-md shadow-md bg-slate-200'>
<div className='w-96 p-4 rounded-md shadow-md bg-slate-200'>
model two
<div className='cursor-pointer p-2 border' onClick={showModel}>
show
@@ -71,3 +75,130 @@ const ModelTwo = () => {
</div>
);
};
const ModelTwo2 = () => {
const ref = useRef<HTMLDivElement>(null);
const showModel = () => {
const div = createDOMElement(refHide);
const model = DialogModal.render(ref.current! || div, {
dialogTitle: 'Dialog Modal',
width: '400px',
dialogTitleCloseIcon: true,
contentStyle: {
// maxHeight: '100px',
// overflow: 'auto',
},
});
};
const refHide = (
<div ref={ref}>
Modal Dialog
<div></div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
);
return (
<div>
<div className='w-96 p-4 rounded-md shadow-md bg-slate-200'>
model two -ref的模块没有真实渲染到节点createDOMElement
<div className='cursor-pointer p-2 border' onClick={showModel}>
show
</div>
<div className='hidden'>{refHide}</div>
</div>
</div>
);
};
const ModelThree = () => {
const ref = useRef<HTMLDivElement>(null);
let dialog = useRef<DialogModal | null>(null);
const showModel = () => {
const model = DialogModal.render(ref.current!, {
dialogTitle: 'Dialog Modal',
width: '400px',
dialogTitleCloseIcon: true,
open: false,
contentStyle: {
// maxHeight: '100px',
// overflow: 'auto',
},
});
const modals = modalStore.getState().modals;
console.log('modals', modals.length, model);
dialog.current = model;
};
return (
<div>
<div className='w-96 p-4 rounded-md shadow-md bg-slate-200'>
model 3
<div className='cursor-pointer p-2 border' onClick={showModel}>
show
</div>
<div ref={ref}>
Modal Dialog
<div></div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
<div
onClick={() => {
if (dialog.current) {
dialog.current.setOpen(true);
}
console.log('open', dialog.current);
}}>
</div>
</div>
</div>
);
};
const Model4 = () => {
const ref = useRef<HTMLDivElement>(null);
let dialog = useRef<DialogModal | null>(null);
const showModel = () => {
const model = DialogModal.create({
dialogTitle: 'Dialog Modal',
width: '400px',
dialogTitleCloseIcon: true,
open: false,
contentStyle: {
// maxHeight: '100px',
// overflow: 'auto',
},
});
const modals = modalStore.getState().modals;
console.log('modals', modals.length, model);
dialog.current = model;
};
return (
<div>
<div className='w-96 p-4 rounded-md shadow-md bg-slate-200'>
model 4
<div className='cursor-pointer p-2 border' onClick={showModel}>
show
</div>
<div ref={ref}>
Modal Dialog
<div></div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
<div
onClick={() => {
if (dialog.current) {
dialog.current.setOpen(true);
}
console.log('open', dialog.current);
}}>
</div>
</div>
</div>
);
};

View File

@@ -0,0 +1,20 @@
class A {
constructor() {}
// 使用泛型和类构造函数签名来推断返回的类型
static render<T extends new (...args: any[]) => any>(this: T, el: string | HTMLDivElement): InstanceType<T> {
return new this();
}
}
class B extends A {
constructor() {
super();
}
}
const a = A.render('div');
const b = B.render('div');
// type a == A
// type b == B