-
+
+
+
+ {
+ componentsId && componentsLibrary[componentsId](data)
+ }
+
+
+ {
+ JSON.stringify(widgets)
+ }
+
);
diff --git a/components/Draggable/utils/index.ts b/components/Draggable/utils/index.ts
index 3cf1501..1bfc787 100644
--- a/components/Draggable/utils/index.ts
+++ b/components/Draggable/utils/index.ts
@@ -4,6 +4,6 @@
* @param [x=16] 推荐使用偶数
* @returns 最近的 x 的倍数
*/
-export function nearestMultiple(n: number, x: number = 32): number {
+export function nearestMultiple(n: number, x: number = 18): number {
return Math.floor((n + x/2) / x) * x;
}
diff --git a/components/DraggablePanel.tsx b/components/DraggablePanel.tsx
index 1cd2704..93cc49f 100644
--- a/components/DraggablePanel.tsx
+++ b/components/DraggablePanel.tsx
@@ -43,7 +43,7 @@ export default function DraggablePanel(props: DraggablePanelType) {
PreviewStore.clearPreview();
ComponentStore.changeComponent({
id: event?.active?.data?.current?.id,
- component: event?.active?.data?.current?.component,
+ componentsId: event?.active?.data?.current?.componentsId,
x,
y,
width: nearestMultiple(width),
diff --git a/hooks/useDynamicWidgets.ts b/hooks/useDynamicWidgets.ts
new file mode 100644
index 0000000..fa88bd9
--- /dev/null
+++ b/hooks/useDynamicWidgets.ts
@@ -0,0 +1,68 @@
+import { useState, useCallback, useEffect } from 'react';
+import dynamic from 'next/dynamic';
+
+export interface WidgetModule {
+ id: string;
+ name: string;
+ version: string;
+ component: ReturnType
;
+}
+
+export const useDynamicWidgets = (): {
+ widgets: WidgetModule[];
+ refreshWidgets: () => Promise;
+} => {
+ const [widgets, setWidgets] = useState([]);
+
+ const loadWidgets = useCallback(async () => {
+ try {
+ // Webpack 的 require.context 匹配 widgets 目录
+ const context = require.context('../widgets', true, /\/index\.tsx$/);
+ console.log("[DEBUG] Matched files:", context.keys());
+
+
+
+ const modules = await Promise.all(
+ context.keys().map(async (key) => {
+ const folderName = key.split('/')[1];
+
+ // 动态导入元数据
+ console.log("[DEBUG] import files:", `../widgets/${folderName}/index.tsx`);
+
+ const meta = await import(`../widgets/${folderName}/index.tsx`);
+
+ // 创建动态组件(单独导入确保 Tree Shaking)
+ const Component = dynamic(
+ () => import(`../widgets/${folderName}/index.tsx`),
+ { 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, refreshWidgets };
+};
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..a7e86fe 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,17 @@
import type { NextConfig } from "next";
-const nextConfig: NextConfig = {
- /* config options here */
+// next.config.js
+const nextConfig:NextConfig = {
+ // 移除自定义 webpack 配置,Next.js 已内置 TypeScript 支持
+ // 保留以下配置即可
+ experimental: {
+ externalDir: true, // 如果需要引用外部目录
+ },
+ webpack: (config) => {
+ // 保留其他必要配置
+ return config;
+ },
};
+
export default nextConfig;
diff --git a/widgets/Logo/index copy.tsx b/widgets/Logo/index copy.tsx
new file mode 100644
index 0000000..8a5a00d
--- /dev/null
+++ b/widgets/Logo/index copy.tsx
@@ -0,0 +1,15 @@
+"use client";
+import "@/app/globals.css";
+
+export const id = "logo";
+export const name = "Logo";
+export const version = "1.0.0";
+export default function Logo() {
+ return (
+
+
+ NEXUSHUB
+
+
+ );
+}
diff --git a/components/Logo/index.tsx b/widgets/Logo/index.tsx
similarity index 77%
rename from components/Logo/index.tsx
rename to widgets/Logo/index.tsx
index 4c2a0ca..8a5a00d 100644
--- a/components/Logo/index.tsx
+++ b/widgets/Logo/index.tsx
@@ -1,6 +1,9 @@
"use client";
import "@/app/globals.css";
+export const id = "logo";
+export const name = "Logo";
+export const version = "1.0.0";
export default function Logo() {
return (
diff --git a/components/Text/index.tsx b/widgets/Text/index.tsx
similarity index 92%
rename from components/Text/index.tsx
rename to widgets/Text/index.tsx
index f790296..3835c6f 100644
--- a/components/Text/index.tsx
+++ b/widgets/Text/index.tsx
@@ -1,6 +1,9 @@
import React, { CSSProperties } from 'react';
-import { DraggablePropsType } from '../Draggable/Draggable';
+import { DraggablePropsType } from '../../components/Draggable/Draggable';
+export const id = "text";
+export const name = "文字";
+export const version = "1.0.0";
type FontData = {
content: string;
fontSize?: number; // 字体大小(px)