Skip to content

Commit 44fd9de

Browse files
committed
refactor: rewrite reducer for slots and introduce walkTree lib
1 parent f8b429b commit 44fd9de

22 files changed

+632
-853
lines changed

packages/core/components/DropZone/context.tsx

+21-21
Original file line numberDiff line numberDiff line change
@@ -84,35 +84,35 @@ export const DropZoneProvider = ({
8484

8585
const registerZone = useCallback(
8686
(zoneCompound: string) => {
87-
if (!dispatch) {
88-
return;
89-
}
87+
// if (!dispatch) {
88+
// return;
89+
// }
9090

91-
// dispatch({
92-
// type: "registerZone",
93-
// zone: zoneCompound,
94-
// });
91+
dispatch({
92+
type: "registerZone",
93+
zone: zoneCompound,
94+
});
9595

96-
setActiveZones((latest) => ({ ...latest, [zoneCompound]: true }));
96+
// setActiveZones((latest) => ({ ...latest, [zoneCompound]: true }));
9797
},
9898
[setActiveZones, dispatch]
9999
);
100100

101101
const unregisterZone = useCallback(
102102
(zoneCompound: string) => {
103-
if (!dispatch) {
104-
return;
105-
}
106-
107-
// dispatch({
108-
// type: "unregisterZone",
109-
// zone: zoneCompound,
110-
// });
111-
112-
setActiveZones((latest) => ({
113-
...latest,
114-
[zoneCompound]: false,
115-
}));
103+
// if (!dispatch) {
104+
// return;
105+
// }
106+
107+
dispatch({
108+
type: "unregisterZone",
109+
zone: zoneCompound,
110+
});
111+
112+
// setActiveZones((latest) => ({
113+
// ...latest,
114+
// [zoneCompound]: false,
115+
// }));
116116
},
117117
[setActiveZones, dispatch]
118118
);

packages/core/components/DropZone/index.tsx

+21-16
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ const DropZoneChild = ({
124124

125125
const contentItem = useAppStore(
126126
useShallow((s) => {
127-
return s.state.indexes.nodes[componentId]?.data;
127+
return s.state.indexes.nodes[componentId]?.flatData;
128128
})
129129
);
130130

@@ -275,31 +275,36 @@ const DropZoneEdit = forwardRef<HTMLDivElement, DropZoneProps>(
275275
return {
276276
isDeepestZone: s.zoneDepthIndex[zoneCompound] ?? false,
277277
inNextDeepestArea: s.nextAreaDepthIndex[areaId || ""],
278-
draggedItemId: s.draggedItem?.id,
279278
draggedComponentType: s.draggedItem?.data.componentType,
280279
userIsDragging: !!s.draggedItem,
281280
};
282281
});
283282

284-
// Register and unregister zone on mount
285-
// TODO cause re-render
286-
// useEffect(() => {
287-
// if (ctx?.registerZone) {
288-
// ctx?.registerZone(zoneCompound);
289-
// }
290-
291-
// return () => {
292-
// if (ctx?.unregisterZone) {
293-
// ctx?.unregisterZone(zoneCompound);
294-
// }
295-
// };
296-
// }, []);
297-
298283
const zoneContentIds = useAppStore(
299284
useShallow((s) => {
300285
return s.state.indexes.zones[zoneCompound]?.contentIds;
301286
})
302287
);
288+
const zoneType = useAppStore(
289+
useShallow((s) => {
290+
return s.state.indexes.zones[zoneCompound]?.type;
291+
})
292+
);
293+
294+
// Register and unregister zone on mount
295+
useEffect(() => {
296+
if (!zoneType || zoneType === "dropzone") {
297+
if (ctx?.registerZone) {
298+
ctx?.registerZone(zoneCompound);
299+
}
300+
301+
return () => {
302+
if (ctx?.unregisterZone) {
303+
ctx?.unregisterZone(zoneCompound);
304+
}
305+
};
306+
}
307+
}, [zoneType]);
303308

304309
const contentIds = useMemo(() => {
305310
return zoneContentIds || [];

packages/core/components/Puck/index.tsx

+2-10
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import {
6868
UsePuckStoreContext,
6969
useRegisterUsePuckStore,
7070
} from "../../lib/use-puck";
71-
import { generateNodeIndex, generateZonesIndex } from "../../reducer/indexes";
71+
import { walkTree } from "../../lib/walk-tree";
7272

7373
const getClassName = getClassNameFactory("Puck", styles);
7474
const getLayoutClassName = getClassNameFactory("PuckLayout", styles);
@@ -286,15 +286,7 @@ function PuckProvider<
286286
},
287287
} as G["UserAppState"];
288288

289-
const indexes = {
290-
nodes: generateNodeIndex(newAppState, config),
291-
zones: generateZonesIndex(newAppState),
292-
};
293-
294-
return {
295-
...newAppState,
296-
indexes,
297-
};
289+
return walkTree(newAppState);
298290
});
299291

300292
const { appendData = true } = _initialHistory || {};

packages/core/lib/apply-dynamic-props.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { ComponentData, Data, RootData } from "../types";
2-
import { dataMap } from "./data-map";
32

43
/**
54
* Apply the provided data to the Puck data payload.

packages/core/lib/data-map.ts

-55
This file was deleted.

packages/core/lib/deindex.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { ComponentData } from "../types";
2+
import { NodeIndex, PrivateAppState, ZoneIndex } from "../types/Internal";
3+
import { forEachSlot } from "./for-each-slot";
4+
import { forRelatedZones } from "./for-related-zones";
5+
6+
export const deindex = (
7+
state: PrivateAppState,
8+
componentData: ComponentData
9+
) => {
10+
let zones: ZoneIndex = { ...state.indexes.zones };
11+
let nodes: NodeIndex = { ...state.indexes.nodes };
12+
13+
const dindexRelatedZones = (item: ComponentData) => {
14+
forRelatedZones(item, state.data, (_path, zoneCompound, content) => {
15+
content.forEach((subItem) => {
16+
dindexChildren(subItem);
17+
delete nodes[subItem.props.id];
18+
});
19+
20+
delete zones[zoneCompound];
21+
});
22+
};
23+
24+
const dindexChildren = (item: ComponentData) => {
25+
forEachSlot(
26+
item,
27+
(parentId, slotId, content) => {
28+
const zoneCompound = `${parentId}:${slotId}`;
29+
30+
delete zones[zoneCompound];
31+
32+
content.forEach((item) => {
33+
dindexRelatedZones(item);
34+
35+
delete nodes[item.props.id];
36+
});
37+
},
38+
true
39+
);
40+
};
41+
42+
dindexRelatedZones(componentData);
43+
dindexChildren(componentData);
44+
45+
delete nodes[componentData.props.id];
46+
47+
return { nodes, zones };
48+
};

packages/core/lib/flatten-data.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
import { Config, UserGenerics } from "../types";
2-
import { flattenAllSlots } from "./flatten-slots";
1+
import { ComponentData, Config, UserGenerics } from "../types";
2+
import { PrivateAppState } from "../types/Internal";
3+
import { walkTree } from "./walk-tree";
34

45
export const flattenData = <
56
UserConfig extends Config = Config,
67
G extends UserGenerics<UserConfig> = UserGenerics<UserConfig>
78
>(
8-
data: G["UserData"]
9+
state: PrivateAppState<G["UserData"]>
910
) => {
10-
const slots = flattenAllSlots(data);
11-
const slotsAndZones = {
12-
...(data.zones || {}),
13-
...slots,
14-
} as Record<string, G["UserData"]["content"]>;
11+
const data: ComponentData[] = [];
1512

16-
return Object.keys(slotsAndZones).reduce<G["UserComponentData"][]>(
17-
(acc, zone) => [...acc, ...slotsAndZones[zone]],
18-
data.content
13+
walkTree(
14+
state,
15+
(content) => content,
16+
(item) => {
17+
data.push(item);
18+
19+
return null;
20+
}
1921
);
22+
23+
return data;
2024
};

0 commit comments

Comments
 (0)