Skip to content

Instantly share code, notes, and snippets.

@barteksekula
Created March 27, 2024 16:10
Show Gist options
  • Save barteksekula/913e284aafddc23cb973b43fba9d2266 to your computer and use it in GitHub Desktop.
Save barteksekula/913e284aafddc23cb973b43fba9d2266 to your computer and use it in GitHub Desktop.
import "../editors/editors.scss";
import { DraggableProvidedDragHandleProps } from "@hello-pangea/dnd";
import classnames from "classnames";
import { useEffect, useRef } from "react";
import DraggableIcon from "../common/libraries/drag-and-drop/DraggableIcon.tsx";
import { useComposerDataContext } from "../contexts/composer-data-context.tsx";
import { useComposerPreviewContext } from "../contexts/composer-preview-context.tsx";
import { useComposerSettingsContext } from "../contexts/composer-settings-context.tsx";
import { ILayoutCollection, ILayoutElement, ILayoutItem, LayoutCollectionType, LayoutElementType } from "./layout";
import { LayoutCollection } from "./layout-collection/layout-collection";
import { LayoutElement } from "./layout-element.tsx";
interface LayoutItemProps {
item: ILayoutItem;
rowsIndex?: number;
columnsIndex?: number;
draggableIcon?: boolean;
dragHandleProps?: DraggableProvidedDragHandleProps | null | undefined;
mouseRef?: React.MutableRefObject<Element>;
}
function HoverableElement({ id, children }: any) {
const { setHoveredElementId, hoveredElementId, debouncedHoveredElementId, isPreviewActive } =
useComposerPreviewContext();
const layoutItemRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (
!isPreviewActive.current ||
!layoutItemRef.current ||
!debouncedHoveredElementId ||
id !== debouncedHoveredElementId
) {
return;
}
layoutItemRef.current.scrollIntoView({
behavior: "smooth",
});
}, [debouncedHoveredElementId]);
return (
<div
ref={layoutItemRef}
className={classnames("layout-item", { isHovered: hoveredElementId === id })}
onMouseEnter={() => {
if (!id || id === hoveredElementId) return;
setHoveredElementId(id);
}}
onMouseLeave={() => {
setHoveredElementId(undefined);
}}
>
{children}
</div>
);
}
export const LayoutItem = ({
item,
rowsIndex,
columnsIndex,
draggableIcon,
dragHandleProps,
mouseRef,
}: LayoutItemProps) => {
const { saveProperty } = useComposerDataContext();
const { readonly } = useComposerSettingsContext();
if (!item || !("type" in item)) {
return null;
}
if ("type" in item) {
const type = item["type"];
if (type === LayoutCollectionType.Row || type === LayoutCollectionType.Column) {
return (
<LayoutCollection
layoutItem={item as ILayoutCollection}
rowsIndex={rowsIndex}
parentType={type}
dragHandleProps={dragHandleProps}
draggableIcon={draggableIcon}
columnsIndex={columnsIndex}
mouseRef={mouseRef}
/>
);
}
if (type === LayoutElementType.Element) {
return (
<HoverableElement id={item.id}>
{draggableIcon && !readonly && <DraggableIcon dragHandleProps={dragHandleProps} />}
<LayoutElement
className="layout-element"
layoutElement={item as ILayoutElement}
save={(propertyValue: any) => {
if (!item.id) {
return;
}
saveProperty(item.id, propertyValue);
}}
isReadOnly={!!readonly}
dragHandleProps={dragHandleProps}
draggableIcon={draggableIcon}
rowsIndex={rowsIndex}
parentType={type}
columnsIndex={columnsIndex}
/>
</HoverableElement>
);
}
}
return null;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment