feat: 添加i18n,美化界面

This commit is contained in:
2025-03-20 02:29:01 +08:00
parent 27d9bdf54e
commit c206add7eb
56 changed files with 2743 additions and 928 deletions

View File

@@ -0,0 +1,40 @@
import { useMemo } from 'react';
import { CustomThemeProvider } from '@kevisual/center-components/theme/index.tsx';
import { ToastContainer } from 'react-toastify';
import { FileEditor } from './file-editor/FileEditor';
export const InitProvider = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
type AppProvider = {
key: string;
use: boolean;
};
export type AppProps = {
providers?: AppProvider[];
noProvider?: boolean;
/**
* 是否是单个应用
* 默认是单个应用模块。
*/
isSingleApp?: boolean;
};
export const App = ({ providers, noProvider, isSingleApp = true }: AppProps) => {
const children = useMemo(() => {
return (
<InitProvider>
<FileEditor />
</InitProvider>
);
}, []);
if (noProvider) {
return <>{children}</>;
}
return (
<CustomThemeProvider>
{children}
<ToastContainer />
</CustomThemeProvider>
);
};

View File

@@ -0,0 +1,88 @@
import { createRoot } from 'react-dom/client';
import { App, AppProps } from './App';
import React from 'react';
export class ReactRenderer {
component: any;
element: HTMLElement;
ref: React.RefObject<any>;
props: any;
root: any;
constructor(component: any, { props, className }: any) {
this.component = component;
const el = document.createElement('div');
this.element = el;
this.ref = React.createRef();
this.props = {
...props,
ref: this.ref,
};
el.className = className;
this.root = createRoot(this.element);
this.render();
}
updateProps(props: any) {
this.props = {
...this.props,
...props,
};
this.render();
}
render() {
this.root.render(React.createElement(this.component, this.props));
}
destroy() {
this.root.unmount();
}
}
export default ReactRenderer;
export const randomId = () => {
return Math.random().toString(36).substring(2, 15);
};
export const render = (el: HTMLElement | string, props?: AppProps) => {
const root = typeof el === 'string' ? document.querySelector(el) : el;
if (!root) {
console.error('root not found');
return;
}
const hasResourceApp = window.context?.codemirrorApp;
if (hasResourceApp) {
const render = hasResourceApp as ReactRenderer;
render.updateProps({
props: { t: randomId(), ...props },
});
root.innerHTML = '';
root.appendChild(render.element);
} else {
const renderer = new ReactRenderer(App, {
props: { ...props },
className: 'codemirror-root w-full h-full',
});
if (window.context) {
window.context.codemirrorApp = renderer;
} else {
window.context = {
codemirrorApp: renderer,
};
}
root.appendChild(renderer.element);
}
};
export const unmount = (el: HTMLElement | string) => {
const root = typeof el === 'string' ? document.querySelector(el) : el;
if (!root) {
console.error('root not found');
return;
}
const hasResourceApp = window.context?.codemirrorApp;
if (hasResourceApp) {
const render = hasResourceApp as ReactRenderer;
render.destroy();
window.context.codemirrorApp = null;
}
};

View File

@@ -0,0 +1,17 @@
import { useEffect, useRef } from 'react';
import { BaseEditor } from '../../editor/editor';
export const FileEditor = () => {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const editor = new BaseEditor();
if (containerRef.current) {
editor.createEditor(containerRef.current);
}
return () => {
editor.destroyEditor();
};
}, []);
return <div ref={containerRef} className='w-full h-full'></div>;
};