-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathgrid-stack-render.tsx
More file actions
69 lines (60 loc) · 1.85 KB
/
grid-stack-render.tsx
File metadata and controls
69 lines (60 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { createPortal } from "react-dom";
import { useGridStackContext } from "./grid-stack-context";
import { useGridStackRenderContext } from "./grid-stack-render-context";
import { GridStackWidgetContext } from "./grid-stack-widget-context";
import { GridStackWidget } from "gridstack";
import { ComponentType } from "react";
export interface ComponentDataType<T = object> {
name: string;
props: T;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ComponentMap = Record<string, ComponentType<any>>;
function parseWeightMetaToComponentData(
meta: GridStackWidget
): ComponentDataType & { error: unknown } {
let error = null;
let name = "";
let props = {};
try {
if (meta.content) {
const result = JSON.parse(meta.content) as {
name: string;
props: object;
};
name = result.name;
props = result.props;
}
} catch (e) {
error = e;
}
return {
name,
props,
error,
};
}
export function GridStackRender(props: { componentMap: ComponentMap }) {
const { _rawWidgetMetaMap } = useGridStackContext();
const { getWidgetContainer } = useGridStackRenderContext();
return (
<>
{Array.from(_rawWidgetMetaMap.value.entries()).map(([id, meta]) => {
const componentData = parseWeightMetaToComponentData(meta);
const WidgetComponent = props.componentMap[componentData.name];
const widgetContainer = getWidgetContainer(id);
if (!widgetContainer) {
throw new Error(`Widget container not found for id: ${id}`);
}
return (
<GridStackWidgetContext.Provider key={id} value={{ widget: { id } }}>
{createPortal(
<WidgetComponent {...componentData.props} />,
widgetContainer
)}
</GridStackWidgetContext.Provider>
);
})}
</>
);
}