nitropage
Version:
A free and open source, extensible visual page builder based on SolidStart.
57 lines (47 loc) • 1.68 kB
text/typescript
import { orderBy } from "es-toolkit";
import { Accessor, createMemo, useContext } from "solid-js";
import { BlueprintSlot, ElementSlot } from "../../../../../types";
import { StateContext } from "../../../../lib/context/page";
import { ElementDescriptor } from "./useElementDescriptor";
export type ElementSlot_ = {
key: string;
title: string;
slot?: ElementSlot;
blueprint?: BlueprintSlot;
invalid?: boolean;
};
export const useElementSlots = (
id_: () => string | undefined,
descriptor: Accessor<ElementDescriptor>,
) => {
const [state] = useContext(StateContext)!;
return createMemo(() => {
const result = {} as Record<string, ElementSlot_>;
const id = id_();
if (!id) return result;
const descriptorSlots = descriptor().slots;
const slotKeys = Object.keys(descriptorSlots);
for (const key of slotKeys) {
const slotConfig =
descriptorSlots[key as unknown as keyof typeof descriptorSlots];
result[key] = {
key,
title: slotConfig.title ?? key,
blueprint: descriptor().type === "blueprint" ? slotConfig : undefined,
};
}
// If a slot was renamed or removed in the blueprint, but still has elements in the database,
// then the slot will appear here
const element = state.elements[id];
for (const [key, id] of Object.entries(element.slots)) {
const slot = state.slots[id];
if (result[key] || slot?.elements.length) {
result[key] ??= { invalid: true, title: key, key };
result[key].slot = slot;
}
}
return result;
});
};
export const sortElementSlots = (slots: ElementSlot_[]) =>
orderBy(slots, ["title"], ["asc"]);