111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
"use client";
|
||
import { useState, useCallback, useEffect, ReactNode } from 'react';
|
||
import dynamic from 'next/dynamic';
|
||
import { DraggablePropsType } from '@/components/Draggable/Draggable';
|
||
import * as Logo from '@/widgets/Logo/index';
|
||
import * as Text from '@/widgets/Text/index';
|
||
import * as Image from '@/widgets/Image/index';
|
||
export interface WidgetModule {
|
||
id: string;
|
||
name: string;
|
||
version: string;
|
||
defaultConfig: (data: Record<string, unknown>) => Record<string, unknown>
|
||
}
|
||
|
||
export type widgetsLibraryType = Record<string, (data?:DraggablePropsType['data']) => ReactNode>;
|
||
|
||
const widgetPaths = [
|
||
'@/widgets/Logo/index',
|
||
'@/widgets/Text/index',
|
||
'@/widgets/Image/index',
|
||
];
|
||
|
||
export const useWidgets = (): {
|
||
widgets: WidgetModule[];
|
||
widgetsLibrary: widgetsLibraryType;
|
||
refreshWidgets: () => Promise<void>;
|
||
} => {
|
||
const [widgets, setWidgets] = useState<WidgetModule[]>([
|
||
{
|
||
id: 'logo',
|
||
name: 'Logo',
|
||
version: '1.0.0',
|
||
defaultConfig: Logo.defaultConfig
|
||
},
|
||
{
|
||
id: 'text',
|
||
name: '文本',
|
||
version: '1.0.0',
|
||
defaultConfig: Text.defaultConfig
|
||
},
|
||
{
|
||
id: 'image',
|
||
name: '图片',
|
||
version: '1.0.0',
|
||
defaultConfig: Image.defaultConfig
|
||
|
||
},
|
||
]);
|
||
const [widgetsLibrary, setWidgetsLibrary] = useState<widgetsLibraryType>({
|
||
'logo': (data) => {
|
||
const { default:Component, defaultConfig } = Logo;
|
||
|
||
return <Component {...defaultConfig(data)} />
|
||
},
|
||
'text': (data) => {
|
||
const { default:Component, defaultConfig } = Text;
|
||
return <Component data={defaultConfig(data)} />
|
||
},
|
||
'image': (data) => {
|
||
const { default:Component, defaultConfig } = Image;
|
||
return <Component data={defaultConfig(data)} />
|
||
}
|
||
});
|
||
|
||
const loadWidgets = useCallback(async () => {
|
||
try {
|
||
// Webpack 的 require.context 匹配 widgets 目录
|
||
console.log(window);
|
||
// const modules = await Promise.all(
|
||
// widgetPaths.map(async (key) => {
|
||
// console.log(key);
|
||
// debugger
|
||
// const meta = await require(key);
|
||
|
||
|
||
// // 创建动态组件(单独导入确保 Tree Shaking)
|
||
// // const Component = dynamic(
|
||
// // () => import(key),
|
||
// // { ssr: false }
|
||
// // );
|
||
|
||
// return {
|
||
// id: meta.id,
|
||
// name: meta.name,
|
||
// version: meta.version,
|
||
// // component: Component
|
||
// };
|
||
// })
|
||
// );
|
||
// console.log(modules);
|
||
|
||
// setWidgets(modules);
|
||
} catch (error) {
|
||
console.error('Failed to load widgets:', error);
|
||
setWidgets([]);
|
||
}
|
||
}, []);
|
||
|
||
// 初始化加载
|
||
// useEffect(() => {
|
||
// loadWidgets();
|
||
// }, [loadWidgets]);
|
||
|
||
// 暴露刷新方法
|
||
const refreshWidgets = useCallback(async () => {
|
||
await loadWidgets();
|
||
}, [loadWidgets]);
|
||
|
||
return { widgets, widgetsLibrary, refreshWidgets };
|
||
};
|