1
0
mirror of synced 2025-12-12 21:17:58 +08:00

feat: 将ui-react中的组件独立成包

This commit is contained in:
roymondchen
2024-08-13 20:35:14 +08:00
committed by roymondchen
parent 60d2b64aa5
commit cab36b49a3
93 changed files with 1772 additions and 741 deletions

View File

@@ -0,0 +1,61 @@
{
"version": "0.0.1",
"name": "@tmagic/react-runtime-help",
"type": "module",
"sideEffects": false,
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./*": "./*"
},
"files": [
"dist"
],
"license": "Apache-2.0",
"scripts": {
"build": "pnpm clean && tsc -b tsconfig.build.json",
"clean": "rimraf dist *.tsbuildinfo",
"check:type": "tsc --noEmit --project tsconfig.build.json"
},
"engines": {
"node": ">=18"
},
"repository": {
"type": "git",
"url": "https://github.com/Tencent/tmagic-editor.git"
},
"dependencies": {
"lodash-es": "^4.17.21"
},
"peerDependencies": {
"lodash-es": "^4.17.21",
"@tmagic/core": "workspace:*",
"@tmagic/data-source": "workspace:*",
"@tmagic/schema": "workspace:*",
"@tmagic/stage": "workspace:*",
"@tmagic/utils": "workspace:*",
"react": ">=18.3.1",
"typescript": "*"
},
"peerDependenciesMeta": {
"@tmagic/schema": {
"optional": true
},
"@tmagic/stage": {
"optional": true
},
"typescript": {
"optional": true
}
},
"devDependencies": {
"@types/lodash-es": "^4.17.4",
"@types/node": "^18.19.0",
"@types/react": "^18.3.3",
"rimraf": "^3.0.2"
}
}

View File

@@ -0,0 +1,23 @@
/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import type TMagicApp from '@tmagic/core';
export default React.createContext<TMagicApp | undefined>(undefined);

View File

@@ -0,0 +1,77 @@
/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useContext, useEffect, useState } from 'react';
import type TMagicApp from '@tmagic/core';
import type { Id, MNodeInstance } from '@tmagic/schema';
import { isDslNode } from '@tmagic/utils';
import AppContent from '../AppContent';
interface UseAppOptions<T extends MNodeInstance = MNodeInstance> {
config: T;
iteratorContainerId?: Id[];
iteratorIndex?: number[];
methods?: {
[key: string]: Function;
};
}
export const useApp = ({ methods = {}, config, iteratorContainerId, iteratorIndex }: UseAppOptions) => {
const app: TMagicApp | undefined = useContext(AppContent);
const emitData = {
config,
...methods,
};
const display = <T extends MNodeInstance>(config: T) => {
if (config.visible === false) return false;
if (config.condResult === false) return false;
const displayCfg = config.display;
if (typeof displayCfg === 'function') {
return displayCfg(app);
}
return displayCfg !== false;
};
const node = isDslNode(config) && config.id ? app?.getNode(config.id, iteratorContainerId, iteratorIndex) : undefined;
const [created, setCreated] = useState(false);
if (node) {
if (!created) {
// 只需要触发一次 created
setCreated(true);
node?.emit('created', emitData);
}
useEffect(() => {
node?.emit('mounted', emitData);
return () => {
node?.emit('destroy', emitData);
};
}, []);
}
return { app, node, display };
};

View File

@@ -0,0 +1,44 @@
import { useEffect, useState } from 'react';
import { cloneDeep } from 'lodash-es';
import TMagicApp from '@tmagic/core';
import type { ChangeEvent } from '@tmagic/data-source';
import type { MNode } from '@tmagic/schema';
import { isPage, replaceChildNode } from '@tmagic/utils';
export const useDsl = (app: TMagicApp | undefined) => {
if (!app?.page) return null;
const [pageConfig, setPageConfig] = useState(app.page.data);
const updateDataHandler = (nodes: MNode[], sourceId: string, event: ChangeEvent) => {
let config = pageConfig;
nodes.forEach((node) => {
if (isPage(node)) {
config = node;
} else {
replaceChildNode(node, [config]);
}
});
setPageConfig(cloneDeep(config));
setTimeout(() => {
app.emit('replaced-node', {
...event,
nodes,
sourceId,
});
}, 0);
};
useEffect(() => {
app.dataSourceManager?.on('update-data', updateDataHandler);
return () => {
app.dataSourceManager?.off('update-data', updateDataHandler);
};
}, []);
return { pageConfig };
};

View File

@@ -0,0 +1,66 @@
import { cloneDeep } from 'lodash-es';
import Core from '@tmagic/core';
import type { Id, MApp } from '@tmagic/schema';
import type { Magic, RemoveData, SortEventData, UpdateData } from '@tmagic/stage';
import { getElById, replaceChildNode } from '@tmagic/utils';
declare global {
interface Window {
magic?: Magic;
}
}
export const useEditorDsl = (app: Core | undefined, renderDom: () => void) => {
let curPageId: Id = '';
const updateConfig = (root: MApp) => {
app?.setConfig(root, curPageId);
renderDom();
};
window.magic?.onRuntimeReady({
getApp() {
return app;
},
updateRootConfig(root: MApp) {
app?.setConfig(root);
},
updatePageId(id: Id) {
curPageId = id;
app?.setPage(curPageId);
renderDom();
},
select(id: Id) {
const el = getElById()(document, id);
if (el) return el;
// 未在当前文档下找到目标元素,可能是还未渲染,等待渲染完成后再尝试获取
return new Promise((resolve) => {
setTimeout(() => {
resolve(getElById()(document, id));
}, 0);
});
},
add({ root }: UpdateData) {
updateConfig(root);
},
update({ config, root, parentId }: UpdateData) {
const newNode = app?.dataSourceManager?.compiledNode(config, undefined, true) || config;
replaceChildNode(newNode, [root], parentId);
updateConfig(cloneDeep(root));
},
sortNode({ root }: SortEventData) {
root && updateConfig(root);
},
remove({ root }: RemoveData) {
updateConfig(root);
},
});
};

View File

@@ -0,0 +1,21 @@
/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { default as AppContent } from './AppContent';
export * from './hooks/use-editor-dsl';
export * from './hooks/use-dsl';
export * from './hooks/use-app';

View File

@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"declaration": true,
"sourceMap": false,
"types": ["node"],
},
"include": ["./src"],
}

View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./",
"jsx": "react",
"forceConsistentCasingInFileNames": true,
"types": ["node"],
},
}